import os, unittest
from django.db import settings
from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis.utils import GeoIP, GeoIPException

# Note: Requires use of both the GeoIP country and city datasets.
# The GEOIP_DATA path should be the only setting set (the directory
# should contain links or the actual database files 'GeoIP.dat' and 
# 'GeoLiteCity.dat'.
class GeoIPTest(unittest.TestCase):
    
    def test01_init(self):
        "Testing GeoIP initialization."
        g1 = GeoIP() # Everything inferred from GeoIP path
        path = settings.GEOIP_PATH
        g2 = GeoIP(path, 0) # Passing in data path explicitly.
        g3 = GeoIP.open(path, 0) # MaxMind Python API syntax.

        for g in (g1, g2, g3):
            self.assertEqual(True, bool(g._country))
            self.assertEqual(True, bool(g._city))
        
        # Only passing in the location of one database.
        city = os.path.join(path, 'GeoLiteCity.dat')
        cntry = os.path.join(path, 'GeoIP.dat')
        g4 = GeoIP(city, country='')
        self.assertEqual(None, g4._country)
        g5 = GeoIP(cntry, city='')
        self.assertEqual(None, g5._city)

        # Improper parameters.
        bad_params = (23, 'foo', 15.23)
        for bad in bad_params:
            self.assertRaises(GeoIPException, GeoIP, cache=bad)
            if isinstance(bad, basestring):
                e = GeoIPException
            else:
                e = TypeError
            self.assertRaises(e, GeoIP, bad, 0)

    def test02_bad_query(self):
        "Testing GeoIP query parameter checking."
        cntry_g = GeoIP(city='<foo>')
        # No city database available, these calls should fail.
        self.assertRaises(GeoIPException, cntry_g.city, 'google.com')
        self.assertRaises(GeoIPException, cntry_g.coords, 'yahoo.com')

        # Non-string query should raise TypeError
        self.assertRaises(TypeError, cntry_g.country_code, 17)
        self.assertRaises(TypeError, cntry_g.country_name, GeoIP)

    def test03_country(self):
        "Testing GeoIP country querying methods."
        g = GeoIP(city='<foo>')
        
        fqdn = 'www.google.com'
        addr = '12.215.42.19'
        
        for query in (fqdn, addr):
            for func in (g.country_code, g.country_code_by_addr, g.country_code_by_name):
                self.assertEqual('US', func(query))
            for func in (g.country_name, g.country_name_by_addr, g.country_name_by_name):
                self.assertEqual('United States', func(query))
            self.assertEqual({'country_code' : 'US', 'country_name' : 'United States'},
                             g.country(query))

    def test04_city(self):
        "Testing GeoIP city querying methods."
        g = GeoIP(country='<foo>')
        
        addr = '130.80.29.3'
        fqdn = 'chron.com'
        for query in (fqdn, addr):
            # Country queries should still work.
            for func in (g.country_code, g.country_code_by_addr, g.country_code_by_name):
                self.assertEqual('US', func(query))
            for func in (g.country_name, g.country_name_by_addr, g.country_name_by_name):
                self.assertEqual('United States', func(query))
            self.assertEqual({'country_code' : 'US', 'country_name' : 'United States'},
                             g.country(query))
            
            # City information dictionary.
            d = g.city(query)
            self.assertEqual('USA', d['country_code3'])
            self.assertEqual('Houston', d['city'])
            self.assertEqual('TX', d['region'])
            self.assertEqual('77002', d['postal_code'])
            self.assertEqual(713, d['area_code'])
            geom = g.geos(query)
            self.failIf(not isinstance(geom, GEOSGeometry))
            lon, lat = (-95.366996765, 29.752300262)
            lat_lon = g.lat_lon(query)
            lat_lon = (lat_lon[1], lat_lon[0])
            for tup in (geom.tuple, g.coords(query), g.lon_lat(query), lat_lon):
                self.assertAlmostEqual(lon, tup[0], 9)
                self.assertAlmostEqual(lat, tup[1], 9)

def suite():
    s = unittest.TestSuite()
    s.addTest(unittest.makeSuite(GeoIPTest))
    return s

def run(verbosity=2):
    unittest.TextTestRunner(verbosity=verbosity).run(suite())
