/**
 * LookupService.java
 *
 * Copyright (C) 2003 MaxMind LLC.  All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package com.maxmind.geoip;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetAddress;
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.StringTokenizer;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

/**
 * Provides a lookup service for information based on an IP address. The location of
 * a database file is supplied when creating a lookup service instance. The edition of
 * the database determines what information is available about an IP address. See the
 * DatabaseInfo class for further details.<p>
 *
 * The following code snippet demonstrates looking up the country that an IP
 * address is from:
 * <pre>
 * // First, create a LookupService instance with the location of the database.
 * LookupService lookupService = new LookupService("c:\\geoip.dat");
 * // Assume we have a String ipAddress (in dot-decimal form).
 * Country country = lookupService.getCountry(ipAddress);
 * System.out.println("The country is: " + country.getName());
 * System.out.println("The country code is: " + country.getCode());
 * </pre>
 *
 * In general, a single LookupService instance should be created and then reused
 * repeatedly.<p>
 *
 * <i>Tip:</i> Those deploying the GeoIP API as part of a web application may find it
 * difficult to pass in a File to create the lookup service, as the location of the
 * database may vary per deployment or may even be part of the web-application. In this
 * case, the database should be added to the classpath of the web-app. For example, by
 * putting it into the WEB-INF/classes directory of the web application. The following code
 * snippet demonstrates how to create a LookupService using a database that can be found
 * on the classpath:
 *
 * <pre>
 * String fileName = getClass().getResource("/GeoIP.dat").toExternalForm().substring(6);
 * LookupService lookupService = new LookupService(fileName);</pre>
 *
 * @author Matt Tucker (matt@jivesoftware.com)
 */
public class LookupService {

    /**
     * Database file.
     */
    private RandomAccessFile file = null;
    private File databaseFile = null;

    /**
     * Information about the database.
     */
    private DatabaseInfo databaseInfo = null;

    /**
     * The database type. Default is the country edition.
     */
    byte databaseType = DatabaseInfo.COUNTRY_EDITION;

    int databaseSegments[];
    int recordLength;
    
    String licenseKey;
    int dnsService = 0;
    int dboptions;
    byte dbbuffer[];
    byte index_cache[];
    long mtime;
    int last_netmask;
    private final static int US_OFFSET = 1;
    private final static int CANADA_OFFSET = 677;
    private final static int WORLD_OFFSET = 1353;
    private final static int FIPS_RANGE = 360;
    private final static int COUNTRY_BEGIN = 16776960;
    private final static int STATE_BEGIN_REV0 = 16700000;
    private final static int STATE_BEGIN_REV1 = 16000000;
    private final static int STRUCTURE_INFO_MAX_SIZE = 20;
    private final static int DATABASE_INFO_MAX_SIZE = 100;
    public final static int GEOIP_STANDARD = 0;
    public final static int GEOIP_MEMORY_CACHE = 1;
    public final static int GEOIP_CHECK_CACHE = 2;
    public final static int GEOIP_INDEX_CACHE = 4;
    public final static int GEOIP_UNKNOWN_SPEED = 0;
    public final static int GEOIP_DIALUP_SPEED = 1;
    public final static int GEOIP_CABLEDSL_SPEED = 2;
    public final static int GEOIP_CORPORATE_SPEED = 3;


    private final static int SEGMENT_RECORD_LENGTH = 3;
    private final static int STANDARD_RECORD_LENGTH = 3;
    private final static int ORG_RECORD_LENGTH = 4;
    private final static int MAX_RECORD_LENGTH = 4;

    private final static int MAX_ORG_RECORD_LENGTH = 300;
    private final static int FULL_RECORD_LENGTH = 60;

    private final Country UNKNOWN_COUNTRY = new Country("--", "N/A");

    private static final HashMap hashmapcountryCodetoindex = new HashMap(512);
    private static final HashMap hashmapcountryNametoindex = new HashMap(512);
    private static final String[] countryCode = {
   "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","CW",
	"AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB",
	"BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO",
	"BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD",
	"CF","CG","CH","CI","CK","CL","CM","CN","CO","CR",
	"CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO",
	"DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ",
	"FK","FM","FO","FR","SX","GA","GB","GD","GE","GF",
	"GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT",
	"GU","GW","GY","HK","HM","HN","HR","HT","HU","ID",
	"IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO",
	"JP","KE","KG","KH","KI","KM","KN","KP","KR","KW",
	"KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT",
	"LU","LV","LY","MA","MC","MD","MG","MH","MK","ML",
	"MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV",
	"MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI",
	"NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF",
	"PG","PH","PK","PL","PM","PN","PR","PS","PT","PW",
	"PY","QA","RE","RO","RU","RW","SA","SB","SC","SD",
	"SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO",
	"SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH",
	"TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW",
	"TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE",
	"VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA",
	"ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE",
  "BL","MF", "BQ"};

    private static final String[] countryName = {
          "N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Curacao",
	"Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados",
	"Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia",
	"Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the",
	"Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica",
	"Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic",
	"Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji",
	"Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","Sint Maarten (Dutch part)","Gabon","United Kingdom","Grenada","Georgia","French Guiana",
	"Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala",
	"Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia",
	"Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan",
	"Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
	"Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania",
	"Luxembourg","Latvia","Libya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali",
	"Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives",
	"Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua",
	"Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia",
	"Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau",
	"Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan",
	"Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname",
	"Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand",
	"Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan",
	"Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela",
	"Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa",
	"Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey",
        "Saint Barthelemy","Saint Martin", "Bonaire, Saint Eustatius and Saba"
	};


    /* init the hashmap once at startup time */
    static {
        int i;
        if(countryCode.length!=countryName.length)
            throw new AssertionError("countryCode.length!=countryName.length");
              
        // distributed service only
        for (i = 0; i < countryCode.length ;i++){
            hashmapcountryCodetoindex.put(countryCode[i],Integer.valueOf(i));
            hashmapcountryNametoindex.put(countryName[i],Integer.valueOf(i));
        }
    };


    /**
     * Create a new distributed lookup service using the license key
     *
     * @param databaseFile String representation of the database file.
     * @param licenseKey license key provided by Maxmind to access distributed service
     */
    public LookupService(String databaseFile,String licenseKey) throws IOException {
        this(new File(databaseFile));
        this.licenseKey = licenseKey;
        dnsService = 1;
    }
    /**
     * Create a new distributed lookup service using the license key
     *
     * @param databaseFile the database file.
     * @param licenseKey license key provided by Maxmind to access distributed service
     */
    public LookupService(File databaseFile,String licenseKey) throws IOException {
        this(databaseFile);
        this.licenseKey = licenseKey;
        dnsService = 1;
    }
    /**
     * Create a new distributed lookup service using the license key
     *
     * @param options  Resevered for future use
     * @param licenseKey license key provided by Maxmind to access distributed service
     */
    public LookupService(int options,String licenseKey) throws IOException {
        this.licenseKey = licenseKey;
        dnsService = 1;
        init();
    }
    /**
     * Create a new lookup service using the specified database file.
     *
     * @param databaseFile String representation of the database file.
     * @throws java.io.IOException if an error occured creating the lookup service
     *      from the database file.
     */
    public LookupService(String databaseFile) throws IOException {
        this(new File(databaseFile));
    }

    /**
     * Create a new lookup service using the specified database file.
     *
     * @param databaseFile the database file.
     * @throws java.io.IOException if an error occured creating the lookup service
     *      from the database file.
     */
    public LookupService(File databaseFile) throws IOException {
        this.databaseFile = databaseFile;
        this.file = new RandomAccessFile(databaseFile, "r");
        init();
    }

    /**
     * Create a new lookup service using the specified database file.
     *
     * @param databaseFile String representation of the database file.
     * @param options database flags to use when opening the database
     * GEOIP_STANDARD read database from disk
     * GEOIP_MEMORY_CACHE cache the database in RAM and read it from RAM
     * @throws java.io.IOException if an error occured creating the lookup service
     *      from the database file.
     */
    public LookupService(String databaseFile, int options) throws IOException{
        this(new File(databaseFile),options);
    }

    /**
     * Create a new lookup service using the specified database file.
     *
     * @param databaseFile the database file.
     * @param options database flags to use when opening the database
     * GEOIP_STANDARD read database from disk
     * GEOIP_MEMORY_CACHE cache the database in RAM and read it from RAM
     * @throws java.io.IOException if an error occured creating the lookup service
     *      from the database file.
     */
    public LookupService(File databaseFile, int options) throws IOException{
        this.databaseFile = databaseFile;
	this.file = new RandomAccessFile(databaseFile, "r");
	dboptions = options;
	init();
    }
    /**
     * Reads meta-data from the database file.
     *
     * @throws java.io.IOException if an error occurs reading from the database file.
     */
    private void init() throws IOException {
        int i, j;
        byte [] delim = new byte[3];
        byte [] buf = new byte[SEGMENT_RECORD_LENGTH];

	if (file == null) {
          return;
	}
	if ((dboptions & GEOIP_CHECK_CACHE) != 0) {
            mtime = databaseFile.lastModified();
	}
	file.seek(file.length() - 3);
        for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
            file.readFully(delim);
            if (delim[0] == -1 && delim[1] == -1 && delim[2] == -1) {
                databaseType = file.readByte();
                if (databaseType >= 106) {
                    // Backward compatibility with databases from April 2003 and earlier
                    databaseType -= 105;
                }
                // Determine the database type.
                if (databaseType == DatabaseInfo.REGION_EDITION_REV0) {
                    databaseSegments = new int[1];
                    databaseSegments[0] = STATE_BEGIN_REV0;
                    recordLength = STANDARD_RECORD_LENGTH;
                }else if (databaseType == DatabaseInfo.REGION_EDITION_REV1){
                    databaseSegments = new int[1];
                    databaseSegments[0] = STATE_BEGIN_REV1;
                    recordLength = STANDARD_RECORD_LENGTH;
		}
                else if (databaseType == DatabaseInfo.CITY_EDITION_REV0 ||
			 databaseType == DatabaseInfo.CITY_EDITION_REV1 ||
			 databaseType == DatabaseInfo.ORG_EDITION ||
			 databaseType == DatabaseInfo.ORG_EDITION_V6 ||
			 databaseType == DatabaseInfo.ISP_EDITION ||
			 databaseType == DatabaseInfo.ISP_EDITION_V6 ||
			 databaseType == DatabaseInfo.DOMAIN_EDITION ||
			 databaseType == DatabaseInfo.DOMAIN_EDITION_V6 ||
			 databaseType == DatabaseInfo.ASNUM_EDITION ||
			 databaseType == DatabaseInfo.ASNUM_EDITION_V6 ||
  			 databaseType == DatabaseInfo.NETSPEED_EDITION_REV1 ||
			 databaseType == DatabaseInfo.NETSPEED_EDITION_REV1_V6 ||
                         databaseType == DatabaseInfo.CITY_EDITION_REV0_V6 ||
			 databaseType == DatabaseInfo.CITY_EDITION_REV1_V6
			 ) {
			databaseSegments = new int[1];
			databaseSegments[0] = 0;
			if (databaseType == DatabaseInfo.CITY_EDITION_REV0 ||
			    databaseType == DatabaseInfo.CITY_EDITION_REV1 ||
			    databaseType == DatabaseInfo.ASNUM_EDITION_V6 ||
                            databaseType == DatabaseInfo.NETSPEED_EDITION_REV1 ||
			    databaseType == DatabaseInfo.NETSPEED_EDITION_REV1_V6 ||
                            databaseType == DatabaseInfo.CITY_EDITION_REV0_V6 ||
			    databaseType == DatabaseInfo.CITY_EDITION_REV1_V6 ||
		      	    databaseType == DatabaseInfo.ASNUM_EDITION) {
			    recordLength = STANDARD_RECORD_LENGTH;
			}
			else {
			    recordLength = ORG_RECORD_LENGTH;
			}
			file.readFully(buf);
			for (j = 0; j < SEGMENT_RECORD_LENGTH; j++) {
			    databaseSegments[0] += (unsignedByteToInt(buf[j]) << (j * 8));
			}
		    }
                break;
            }
            else {
                file.seek(file.getFilePointer() - 4);
            }
        }
        if ((databaseType == DatabaseInfo.COUNTRY_EDITION) ||
            (databaseType == DatabaseInfo.COUNTRY_EDITION_V6) ||
	    (databaseType == DatabaseInfo.PROXY_EDITION) ||
	    (databaseType == DatabaseInfo.NETSPEED_EDITION)) {
            databaseSegments = new int[1];
            databaseSegments[0] = COUNTRY_BEGIN;
            recordLength = STANDARD_RECORD_LENGTH;
        }
        if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
	    int l = (int) file.length();
	    dbbuffer = new byte[l];
	    file.seek(0);
	    file.readFully(dbbuffer,0,l);
	    databaseInfo = this.getDatabaseInfo();
	    file.close();
	}
        if ((dboptions & GEOIP_INDEX_CACHE) != 0) {
          int l = databaseSegments[0] * recordLength * 2;
          index_cache = new byte[l];
          if (index_cache != null){
            file.seek(0);
            file.readFully(index_cache,0,l);     
          }          
        } else {
          index_cache = null;
        }
     }

    /**
     * Closes the lookup service.
     */
    public void close() {
	try {
	    if (file != null){
		file.close();
	    }
            file = null;
        }
        catch (Exception e) { }
    }

    /**
     * Returns the country the IP address is in.
     *
     * @param ipAddress String version of an IPv6 address, i.e. "::127.0.0.1"
     * @return the country the IP address is from.
     */
    public Country getCountryV6(String ipAddress) {
	InetAddress addr;
	try {
	    addr = Inet6Address.getByName(ipAddress);
	}
	catch (UnknownHostException e) {
            return UNKNOWN_COUNTRY;
	}
	return getCountryV6(addr);
    }

    /**
     * Returns the country the IP address is in.
     *
     * @param ipAddress String version of an IP address, i.e. "127.0.0.1"
     * @return the country the IP address is from.
     */
    public Country getCountry(String ipAddress) {
	InetAddress addr;
	try {
	    addr = InetAddress.getByName(ipAddress);
	}
	catch (UnknownHostException e) {
            return UNKNOWN_COUNTRY;
	}
	return getCountry(bytesToLong(addr.getAddress()));
    }

    /**
     * Returns the country the IP address is in.
     *
     * @param ipAddress the IP address.
     * @return the country the IP address is from.
     */
    public synchronized Country getCountry(InetAddress ipAddress) {
        return getCountry(bytesToLong(ipAddress.getAddress()));
    }

    /**
     * Returns the country the IP address is in.
     *
     * @param addr the IP address as Inet6Address.
     * @return the country the IP address is from.
     */
    public Country getCountryV6(InetAddress addr) {
        if (file == null && (dboptions & GEOIP_MEMORY_CACHE) == 0) {
            throw new IllegalStateException("Database has been closed.");
        }
        int ret = seekCountryV6(addr) - COUNTRY_BEGIN;
        if (ret == 0) {
            return UNKNOWN_COUNTRY;
        }
        else {
            return new Country(countryCode[ret], countryName[ret]);
        }
    }

     /**
     * Returns the country the IP address is in.
     *
     * @param ipAddress the IP address in long format.
     * @return the country the IP address is from.
     */
    public Country getCountry(long ipAddress) {
        if (file == null && (dboptions & GEOIP_MEMORY_CACHE) == 0) {
            throw new IllegalStateException("Database has been closed.");
        }
        int ret = seekCountry(ipAddress) - COUNTRY_BEGIN;
        if (ret == 0) {
            return UNKNOWN_COUNTRY;
        }
        else {
            return new Country(countryCode[ret], countryName[ret]);
        }
    }

    public int getID(String ipAddress) {
        InetAddress addr;
        try {
            addr = InetAddress.getByName(ipAddress);
        }
        catch (UnknownHostException e) {
            return 0;
        }
        return getID(bytesToLong(addr.getAddress()));
    }

    public int getID(InetAddress ipAddress) {
        return getID(bytesToLong(ipAddress.getAddress()));
    }

    public synchronized int getID(long ipAddress) {
        if (file == null && (dboptions & GEOIP_MEMORY_CACHE) == 0) {
            throw new IllegalStateException("Database has been closed.");
        }
	int ret = seekCountry(ipAddress) - databaseSegments[0];
	return ret;
    }

    public int last_netmask() {
      return this.last_netmask; 
    }

    public void netmask(int nm){
      this.last_netmask = nm;
    }

    /**
     * Returns information about the database.
     *
     * @return database info.
     */
    public synchronized DatabaseInfo getDatabaseInfo() {
        if (databaseInfo != null) {
            return databaseInfo;
        }
        try {
            _check_mtime();
            boolean hasStructureInfo = false;
            byte [] delim = new byte[3];
            // Advance to part of file where database info is stored.
            file.seek(file.length() - 3);
            for (int i=0; i<STRUCTURE_INFO_MAX_SIZE; i++) {
                int read = file.read( delim );
                if( read==3 && (delim[0]&0xFF)==255 && (delim[1]&0xFF) == 255 && (delim[2]&0xFF)==255 ){
                        hasStructureInfo = true;
                        break;
                }
                file.seek(file.getFilePointer() - 4);

            }
            if (hasStructureInfo) {
                    file.seek(file.getFilePointer() - 6);
            }
            else {
                // No structure info, must be pre Sep 2002 database, go back to end.
                file.seek(file.length() - 3);
            }
            // Find the database info string.
            for (int i=0; i<DATABASE_INFO_MAX_SIZE; i++) {
                file.readFully(delim);
                    if (delim[0]==0 && delim[1]==0 && delim[2]==0) {
                        byte[] dbInfo = new byte[i];
                    file.readFully(dbInfo);
                        // Create the database info object using the string.
                        this.databaseInfo = new DatabaseInfo(new String(dbInfo));
                        return databaseInfo;
                    }
                    file.seek(file.getFilePointer() -4);
                }
            }
        catch (Exception e) {
            e.printStackTrace();
        }
        return new DatabaseInfo("");
    }

    synchronized void _check_mtime(){
      try {
        if ((dboptions & GEOIP_CHECK_CACHE) != 0){
          long t = databaseFile.lastModified();
          if (t != mtime){
            /* GeoIP Database file updated */
            /* refresh filehandle */
            close();
            file = new RandomAccessFile(databaseFile,"r");
	    databaseInfo = null;
	    init();
          }
        }
      } catch (IOException e) {
        System.out.println("file not found");
      }
    }

    // for GeoIP City only
    public Location getLocationV6(String str) {
        if (dnsService == 0) {
            InetAddress addr;
            try {
                addr = InetAddress.getByName(str);
            }
            catch (UnknownHostException e) {
                return null;
            }

            return getLocationV6(addr);
        } else {
            String str2 = getDnsAttributes(str);
 	    return getLocationwithdnsservice(str2);
	    // TODO if DNS is not available, go to local file as backup
	}
    }

    // for GeoIP City only
    public Location getLocation(InetAddress addr) {
        return getLocation(bytesToLong(addr.getAddress()));
    }

    // for GeoIP City only
    public Location getLocation(String str) {
        if (dnsService == 0) {
            InetAddress addr;
            try {
                addr = InetAddress.getByName(str);
            }
            catch (UnknownHostException e) {
                return null;
            }

            return getLocation(addr);
        } else {
            String str2 = getDnsAttributes(str);
 	    return getLocationwithdnsservice(str2);
	    // TODO if DNS is not available, go to local file as backup
	}
    }

    String getDnsAttributes(String ip) {
        try {
            Hashtable env = new Hashtable();
            env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
	    // TODO don't specify ws1, instead use ns servers for s.maxmind.com
            env.put("java.naming.provider.url","dns://ws1.maxmind.com/");

            DirContext ictx = new InitialDirContext(env);
            Attributes attrs = ictx.getAttributes(licenseKey + "." + ip + ".s.maxmind.com", new String[] {"txt"});
            //System.out.println(attrs.get("txt").get());
            String str = attrs.get("txt").get().toString();
            return str;
        }
        catch(NamingException e) {
	    // TODO fix this to handle exceptions
            System.out.println("DNS error");
            return null;
        }

    }

    public Location getLocationwithdnsservice(String str) {
        Location record = new Location();
        String key;
        String value;
        StringTokenizer st = new StringTokenizer(str,";=\""); 
        while (st.hasMoreTokens()) {
	    key = st.nextToken();
            if (st.hasMoreTokens()) {
                value = st.nextToken();
            } else {
	        value = "";}
	    if (key.equals("co")) {
		Integer i = (Integer)hashmapcountryCodetoindex.get(value);
		record.countryCode = value;
		record.countryName = countryName[i.intValue()];
	    }
	    if (key.equals("ci")) {
		record.city = value;
	    }
	    if (key.equals("re")) {
		record.region = value;
	    }
	    if (key.equals("zi")) {
	        record.postalCode = value;
	    }
	    // TODO, ISP and Organization
	    //if (key.equals("or")) {
	    //record.org = value;
	    //}
	    //if (key.equals("is")) {
	    //record.isp = value;
	    //}
	    if (key.equals("la")) {
		try{
		    record.latitude = Float.parseFloat(value);
		} catch(NumberFormatException e) {
		    record.latitude = 0;
		}
	    }
	    if (key.equals("lo")) {
		try{
		    record.longitude = Float.parseFloat(value);
		} catch(NumberFormatException e) {
		    record.latitude = 0;
		}
	    }
	    // dm depreciated use me ( metro_code ) instead
	    if (key.equals("dm") || key.equals("me")) {
		try{
		    record.metro_code = record.dma_code = Integer.parseInt(value);
		} catch(NumberFormatException e) {
		    record.metro_code = record.dma_code = 0;
		}
	    }
	    if (key.equals("ac")) {
		try{
		    record.area_code = Integer.parseInt(value);
		} catch(NumberFormatException e) {
		    record.area_code = 0;
		}
	    }
	}
        return record;
    }

    public synchronized Region getRegion(String str) {
	InetAddress addr;
	try {
	    addr = InetAddress.getByName(str);
	}
	catch (UnknownHostException e) {
	    return null;
	}

	return getRegion(bytesToLong(addr.getAddress()));
    }

    public synchronized Region getRegion(long ipnum) {
        Region record = new Region();
        int seek_region = 0;
        if (databaseType == DatabaseInfo.REGION_EDITION_REV0) {
            seek_region = seekCountry(ipnum) - STATE_BEGIN_REV0;
            char ch[] = new char[2];
            if (seek_region >= 1000) {
                record.countryCode = "US";
                record.countryName = "United States";
                ch[0] = (char)(((seek_region - 1000)/26) + 65);
                ch[1] = (char)(((seek_region - 1000)%26) + 65);
	        record.region = new String(ch);
            } else {
                record.countryCode = countryCode[seek_region];
                record.countryName = countryName[seek_region];
                record.region = "";
            }
        } else if (databaseType == DatabaseInfo.REGION_EDITION_REV1) {
            seek_region = seekCountry(ipnum) - STATE_BEGIN_REV1;
            char ch[] = new char[2];
            if (seek_region < US_OFFSET) {
                record.countryCode = "";
                record.countryName = "";
	        record.region = "";
            } else if (seek_region < CANADA_OFFSET) {
                record.countryCode = "US";
                record.countryName = "United States";
                ch[0] = (char)(((seek_region - US_OFFSET)/26) + 65);
                ch[1] = (char)(((seek_region - US_OFFSET)%26) + 65);
	        record.region = new String(ch);
            } else if (seek_region < WORLD_OFFSET) {
                record.countryCode = "CA";
                record.countryName = "Canada";
                ch[0] = (char)(((seek_region - CANADA_OFFSET)/26) + 65);
                ch[1] = (char)(((seek_region - CANADA_OFFSET)%26) + 65);
	        record.region = new String(ch);
            } else {
                record.countryCode = countryCode[(seek_region - WORLD_OFFSET) / FIPS_RANGE];
                record.countryName = countryName[(seek_region - WORLD_OFFSET) / FIPS_RANGE];
                record.region = "";
            }
	}
	return record;
    }

    public synchronized Location getLocationV6(InetAddress addr) {
        int record_pointer;
        byte record_buf[] = new byte[FULL_RECORD_LENGTH];
        int record_buf_offset = 0;
        Location record = new Location();
        int str_length = 0;
        int j, seek_country;
        double latitude = 0, longitude = 0;

        try {
            seek_country = seekCountryV6(addr);
            if (seek_country == databaseSegments[0]) {
                return null;
            }
            record_pointer = seek_country + (2 * recordLength - 1) * databaseSegments[0];

            if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
                //read from memory
		System.arraycopy(dbbuffer, record_pointer, record_buf, 0, Math.min(dbbuffer.length - record_pointer, FULL_RECORD_LENGTH));
} else {
                //read from disk
                file.seek(record_pointer);
                file.readFully(record_buf);
            }

            // get country
            record.countryCode = countryCode[unsignedByteToInt(record_buf[0])];
            record.countryName = countryName[unsignedByteToInt(record_buf[0])];
            record_buf_offset++;

            // get region
            while (record_buf[record_buf_offset + str_length] != '\0')
                str_length++;
            if (str_length > 0) {
                record.region = new String(record_buf, record_buf_offset, str_length);
            }
            record_buf_offset += str_length + 1;
            str_length = 0;

            // get city
            while (record_buf[record_buf_offset + str_length] != '\0')
                str_length++;
            if (str_length > 0) {
                record.city = new String(record_buf, record_buf_offset, str_length, "ISO-8859-1");
            }
            record_buf_offset += str_length + 1;
            str_length = 0;

            // get postal code
            while (record_buf[record_buf_offset + str_length] != '\0')
                str_length++;
            if (str_length > 0) {
                record.postalCode = new String(record_buf, record_buf_offset, str_length);
            }
            record_buf_offset += str_length + 1;

            // get latitude
            for (j = 0; j < 3; j++)
                latitude += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
            record.latitude = (float) latitude/10000 - 180;
            record_buf_offset += 3;

            // get longitude
            for (j = 0; j < 3; j++)
                longitude += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
	    record.longitude = (float) longitude/10000 - 180;

	    record.dma_code = record.metro_code = 0;
	    record.area_code = 0;
	    if (databaseType == DatabaseInfo.CITY_EDITION_REV1) {
		// get DMA code
		int metroarea_combo = 0;
		if (record.countryCode == "US") {
		    record_buf_offset += 3;
		    for (j = 0; j < 3; j++)
			metroarea_combo += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
		    record.metro_code = record.dma_code = metroarea_combo/1000;
		    record.area_code = metroarea_combo % 1000;
		}
            }
	}
	catch (IOException e) {
            System.err.println("IO Exception while seting up segments");
        }
        return record;
    }

    public synchronized Location getLocation(long ipnum) {
        int record_pointer;
        byte record_buf[] = new byte[FULL_RECORD_LENGTH];
        int record_buf_offset = 0;
        Location record = new Location();
        int str_length = 0;
        int j, seek_country;
        double latitude = 0, longitude = 0;

        try {
            seek_country = seekCountry(ipnum);
            if (seek_country == databaseSegments[0]) {
                return null;
            }
            record_pointer = seek_country + (2 * recordLength - 1) * databaseSegments[0];

            if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
                //read from memory
		System.arraycopy(dbbuffer, record_pointer, record_buf, 0, Math.min(dbbuffer.length - record_pointer, FULL_RECORD_LENGTH));
} else {
                //read from disk
                file.seek(record_pointer);
                file.readFully(record_buf);
            }

            // get country
            record.countryCode = countryCode[unsignedByteToInt(record_buf[0])];
            record.countryName = countryName[unsignedByteToInt(record_buf[0])];
            record_buf_offset++;

            // get region
            while (record_buf[record_buf_offset + str_length] != '\0')
                str_length++;
            if (str_length > 0) {
                record.region = new String(record_buf, record_buf_offset, str_length);
            }
            record_buf_offset += str_length + 1;
            str_length = 0;

            // get city
            while (record_buf[record_buf_offset + str_length] != '\0')
                str_length++;
            if (str_length > 0) {
                record.city = new String(record_buf, record_buf_offset, str_length, "ISO-8859-1");
            }
            record_buf_offset += str_length + 1;
            str_length = 0;

            // get postal code
            while (record_buf[record_buf_offset + str_length] != '\0')
                str_length++;
            if (str_length > 0) {
                record.postalCode = new String(record_buf, record_buf_offset, str_length);
            }
            record_buf_offset += str_length + 1;

            // get latitude
            for (j = 0; j < 3; j++)
                latitude += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
            record.latitude = (float) latitude/10000 - 180;
            record_buf_offset += 3;

            // get longitude
            for (j = 0; j < 3; j++)
                longitude += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
	    record.longitude = (float) longitude/10000 - 180;

	    record.dma_code = record.metro_code = 0;
	    record.area_code = 0;
	    if (databaseType == DatabaseInfo.CITY_EDITION_REV1) {
		// get DMA code
		int metroarea_combo = 0;
		if (record.countryCode == "US") {
		    record_buf_offset += 3;
		    for (j = 0; j < 3; j++)
			metroarea_combo += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
		    record.metro_code = record.dma_code = metroarea_combo/1000;
		    record.area_code = metroarea_combo % 1000;
		}
            }
	}
	catch (IOException e) {
            System.err.println("IO Exception while seting up segments");
        }
        return record;
    }

    public String getOrg(InetAddress addr) {
        return getOrg(bytesToLong(addr.getAddress()));
    }

    public String getOrg(String str) {
        InetAddress addr;
	try {
	    addr = InetAddress.getByName(str);
	}
	catch (UnknownHostException e) {
            return null;
	}
	return getOrg(addr);
    }

    // GeoIP Organization and ISP Edition methods
    public synchronized String getOrg(long ipnum) {
        int seek_org;
        int record_pointer;
        int str_length = 0;
        byte [] buf = new byte[MAX_ORG_RECORD_LENGTH];
        String org_buf;

        try {
            seek_org = seekCountry(ipnum);
            if (seek_org == databaseSegments[0]) {
		return null;
            }

            record_pointer = seek_org + (2 * recordLength - 1) * databaseSegments[0];
            if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
                //read from memory
		System.arraycopy(dbbuffer, record_pointer, buf, 0, Math.min(dbbuffer.length - record_pointer, MAX_ORG_RECORD_LENGTH));
            } else {
		//read from disk
                file.seek(record_pointer);
                try{
                  // read as much as possible
                  file.readFully(buf);
                }
                catch(IOException e){}
            }
            while (buf[str_length] != '\0') {
		str_length++;
            }
            org_buf = new String(buf, 0, str_length, "ISO-8859-1");
            return org_buf;
        }
        catch (IOException e) {
            System.out.println("IO Exception");
            return null;
        }
    }


     public String getOrgV6(String str) {
        InetAddress addr;
	try {
	    addr = InetAddress.getByName(str);
	}
	catch (UnknownHostException e) {
            return null;
	}
	return getOrgV6(addr);
    }

    // GeoIP Organization and ISP Edition methods
    public synchronized String getOrgV6(InetAddress addr) {
        int seek_org;
        int record_pointer;
        int str_length = 0;
        byte [] buf = new byte[MAX_ORG_RECORD_LENGTH];
        String org_buf;

        try {
            seek_org = seekCountryV6(addr);
            if (seek_org == databaseSegments[0]) {
		return null;
            }

            record_pointer = seek_org + (2 * recordLength - 1) * databaseSegments[0];
            if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
                //read from memory
		System.arraycopy(dbbuffer, record_pointer, buf, 0, Math.min(dbbuffer.length - record_pointer, MAX_ORG_RECORD_LENGTH));
            } else {
		//read from disk
                file.seek(record_pointer);
                file.readFully(buf);
            }
            while (buf[str_length] != '\0') {
		str_length++;
            }
            org_buf = new String(buf, 0, str_length, "ISO-8859-1");
            return org_buf;
        }
        catch (IOException e) {
            System.out.println("IO Exception");
            return null;
        }
    }

 


    /**
     * Finds the country index value given an IPv6 address.
     *
     * @param addr the ip address to find in long format.
     * @return the country index.
     */
    private synchronized int seekCountryV6(InetAddress addr) {
        byte [] v6vec = addr.getAddress();
	byte [] buf = new byte[2 * MAX_RECORD_LENGTH];
	int [] x = new int[2];
        int offset = 0;
        _check_mtime();
        for (int depth = 127; depth >= 0; depth--) {
            if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
		//read from memory
                for (int i = 0;i < 2 * MAX_RECORD_LENGTH;i++) {
		    buf[i] = dbbuffer[(2 * recordLength * offset)+i];
		}
            } else if ((dboptions & GEOIP_INDEX_CACHE) != 0) {
                //read from index cache
                for (int i = 0;i < 2 * MAX_RECORD_LENGTH;i++) {
		    buf[i] = index_cache[(2 * recordLength * offset)+i];
		}            
            } else {
		//read from disk 
		try {
                    file.seek(2 * recordLength * offset);
                    file.readFully(buf);
                }
                catch (IOException e) {
                    System.out.println("IO Exception");
                }
            }
            for (int i = 0; i<2; i++) {
                x[i] = 0;
                for (int j = 0; j<recordLength; j++) {
                    int y = buf[i*recordLength+j];
                    if (y < 0) {
                        y+= 256;
                    }
                    x[i] += (y << (j * 8));
                }
            }

            int bnum = 127 - depth;
            int idx = bnum >> 3;
            int b_mask = 1 << ( bnum & 7 ^ 7 );
            if ((v6vec[idx] & b_mask) > 0) {
                if (x[1] >= databaseSegments[0]) {
                    last_netmask = 128 - depth;
                    return x[1];
                }
                offset = x[1];
            }
            else {
                if (x[0] >= databaseSegments[0]) {
                    last_netmask = 128 - depth;
                    return x[0];
                }
                offset = x[0];
	    }
	}

        // shouldn't reach here
        System.err.println("Error seeking country while seeking " + addr.getHostAddress() );
        return 0;
    }
    /**
     * Finds the country index value given an IP address.
     *
     * @param ipAddress the ip address to find in long format.
     * @return the country index.
     */
    private synchronized int seekCountry(long ipAddress) {
	byte [] buf = new byte[2 * MAX_RECORD_LENGTH];
	int [] x = new int[2];
        int offset = 0;
        _check_mtime();
        for (int depth = 31; depth >= 0; depth--) {
            if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
		//read from memory
                for (int i = 0;i < 2 * MAX_RECORD_LENGTH;i++) {
		    buf[i] = dbbuffer[(2 * recordLength * offset)+i];
		}
            } else if ((dboptions & GEOIP_INDEX_CACHE) != 0) {
                //read from index cache
                for (int i = 0;i < 2 * MAX_RECORD_LENGTH;i++) {
		    buf[i] = index_cache[(2 * recordLength * offset)+i];
		}            
            } else {
		//read from disk 
		try {
                    file.seek(2 * recordLength * offset);
                    file.readFully(buf);
                }
                catch (IOException e) {
                    System.out.println("IO Exception");
                }
            }
            for (int i = 0; i<2; i++) {
                x[i] = 0;
                for (int j = 0; j<recordLength; j++) {
                    int y = buf[i*recordLength+j];
                    if (y < 0) {
                        y+= 256;
                    }
                    x[i] += (y << (j * 8));
                }
            }

            if ((ipAddress & (1 << depth)) > 0) {
                if (x[1] >= databaseSegments[0]) {
                    last_netmask = 32 - depth;
                    return x[1];
                }
                offset = x[1];
            }
            else {
                if (x[0] >= databaseSegments[0]) {
                    last_netmask = 32 - depth;
                    return x[0];
                }
                offset = x[0];
	    }
	}

        // shouldn't reach here
        System.err.println("Error seeking country while seeking " + ipAddress);
        return 0;
    }

    /**
     * Returns the long version of an IP address given an InetAddress object.
     *
     * @param address the InetAddress.
     * @return the long form of the IP address.
     */
    private static long bytesToLong(byte [] address) {
        long ipnum = 0;
        for (int i = 0; i < 4; ++i) {
            long y = address[i];
            if (y < 0) {
                y+= 256;
            }
            ipnum += y << ((3-i)*8);
        }
        return ipnum;
    }

    private static int unsignedByteToInt(byte b) {
        return (int) b & 0xFF;
    }
}
