package shaman.hive.udf.service;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;

public class GeoService {
    
    private static class ResourceHolder {
        private static final GeoService geoService = new GeoService();
    }
    
    private DatabaseReader reader;
    
    private GeoService() {
        try {
            reader = new DatabaseReader.Builder(new File("GeoLite2-City.mmdb")).build();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    
    public static GeoService getInstance() {
        return ResourceHolder.geoService;
    }
    
    public String getCountryCode(String ip) {
        try {
            return reader.country(InetAddress.getByName(ip)).getCountry().getIsoCode();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GeoIp2Exception e) {
            e.printStackTrace();
        }
        return "--";
    }
    
    public String getCountryName(String ip) {
        try {
            return reader.country(InetAddress.getByName(ip)).getCountry().getName();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GeoIp2Exception e) {
            e.printStackTrace();
        }
        return "--";
    }
    
    public String getIsp(String ip) {
        try {
            return reader.cityIspOrg(InetAddress.getByName(ip)).getTraits().getIsp();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GeoIp2Exception e) {
            e.printStackTrace();
        }
        return "--";
    }
}

@@ -142,16 +142,64 @@
 ception;
+%0Aimport java.util.HashMap;%0Aimport java.util.Map;
 %0A%0Aimport
@@ -286,16 +286,117 @@
 ception;
+%0Aimport com.maxmind.geoip2.model.CityIspOrgResponse;%0Aimport com.maxmind.geoip2.model.CountryResponse;
 %0A%0Apublic
@@ -531,32 +531,231 @@
 ervice();%0A    %7D%0A
+   %0A    private Map%3CString, CountryResponse%3E countryCache = new HashMap%3CString, CountryResponse%3E();%0A    private Map%3CString, CityIspOrgResponse%3E cityCache = new HashMap%3CString, CityIspOrgResponse%3E();%0A
     %0A    private
@@ -1218,56 +1218,222 @@
     
-return reader.country(InetAddress.getByName(ip))
+CountryResponse cr = countryCache.get(ip);%0A            if (cr == null) %7B%0A                cr = reader.country(InetAddress.getByName(ip));%0A                countryCache.put(ip, cr);%0A            %7D%0A            return cr
 .get
@@ -1788,56 +1788,222 @@
     
-return reader.country(InetAddress.getByName(ip))
+CountryResponse cr = countryCache.get(ip);%0A            if (cr == null) %7B%0A                cr = reader.country(InetAddress.getByName(ip));%0A                countryCache.put(ip, cr);%0A            %7D%0A            return cr
 .get
@@ -2347,59 +2347,222 @@
     
-return reader.cityIspOrg(InetAddress.getByName(ip))
+CityIspOrgResponse ci = cityCache.get(ip);%0A            if (ci == null) %7B%0A                ci = reader.cityIspOrg(InetAddress.getByName(ip));%0A                cityCache.put(ip, ci);%0A            %7D%0A            return ci
 .get

add simple cache to GeoService