let geoLocation = {},
    ip2loc = require("ip2location-nodejs"),
    mmdbreader = require('maxmind-db-reader'),
    winstonLogger = require('./winston');

let geoReader = mmdbreader.openSync(__dirname + '/geoip/GeoIP2-City.mmdb');
ip2loc.IP2Location_init(__dirname + '/IP2LOCATION-LITE-DB11/IP2LOCATION-LITE-DB11.BIN');


(function(geoLocation){
    geoLocation.getCity = function(ip, did, appid){
        winstonLogger.init('fm_city_'+appid, true);
        let obj = {did:did, ip:ip};
        if(!(locData = geoLocation.maxMind(ip))){
            //Fallback to IP2Location db if it failed to fetch data. populateLocationUsingIP2Location
            locData = geoLocation.ip2Locator(ip);
            obj.ip2Loc = true;
        }
        obj.city = (locData.city)? locData.city : false;
        winstonLogger.writeData(obj);
        return (locData.city)? locData.city : false;
    }

    geoLocation.getCountry = function(ip){
      if(!(locData = geoLocation.maxMind(ip))){
          //Fallback to IP2Location db if it failed to fetch data. populateLocationUsingIP2Location
          locData = geoLocation.ip2Locator(ip);
      }
      return (locData.cc)? locData.cc : false;
    }

    geoLocation.getCityAndCountry = function(ip){
      if(!(locData = geoLocation.maxMind(ip))){
          //Fallback to IP2Location db if it failed to fetch data. populateLocationUsingIP2Location
          locData = geoLocation.ip2Locator(ip);
      }
      return (locData.cc && locData.city)? {cc:locData.cc, city:locData.city} : false;
    }

    geoLocation.getLatLng = function(ip){
      if(!(locData = geoLocation.maxMind(ip))){
          //Fallback to IP2Location db if it failed to fetch data. populateLocationUsingIP2Location
          locData = geoLocation.ip2Locator(ip);
      }
      return (locData.lat && locData.lng)? {lat:locData.lat, lng:locData.lng} : false;
    }

    geoLocation.getAll = function(ip){
      if(!(locData = geoLocation.maxMind(ip))){
          //Fallback to IP2Location db if it failed to fetch data. populateLocationUsingIP2Location
          locData = geoLocation.ip2Locator(ip);
      }
      return locData;
    }

    geoLocation.maxMind = function(ip){
        let locationData = {};
        // get geodata
        let geodata = geoReader.getGeoDataSync(ip);
        let foundCity = false;
        if(geodata){
            if(geodata.country){
              locationData.cc = geodata.country.iso_code;
              locationData.country = geodata.country.names.en;
            }

            if(geodata.city){
                locationData.city = geodata.city.names.en;
                foundCity=true;
            }

            if(geodata.location){
                locationData.lat  = geodata.location.latitude;
                locationData.lng = geodata.location.longitude;
            }
        }

       if(foundCity){
          return locationData;
       }
       else {
          return false;
       }
    }

    geoLocation.ip2Locator = function(ip){
        let result = ip2loc.IP2Location_get_all(ip);
        let locationData = {};
         

        if(result && result.city ){
            if (result.city=='-' || result.city=='' || result.city.toLowerCase()=='unknown' ){
                return locationData;
            }
            else{
                if(result.country_short){
                    locationData.cc = result.country_short;
                }

                if(result.country_long){
                    locationData.country = result.country_long;
                }

                if(result.city){
                    locationData.city = result.city;
                }

                if(result.latitude && result.longitude){
                    locationData.lat = result.latitude;
                    locationData.lng = result.longitude;
                }

                return locationData;
            }

        }
        else{
            return locationData;
        }
    }
}(geoLocation));

module.exports = geoLocation;
