package cn.iocoder.yudao.framework.common.util.ip;

import cn.hutool.core.io.IoUtil;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * project test script
 * @author
*/
@Slf4j
public class IPSearcher {
    /**
     **IP数据库地址
     **/
    private static final String DB_PATH = "ip2region.db";
    private static DbSearcher searcher = null;

    static {
        InputStream stream = null;
        try {
            DbConfig config = new DbConfig();
            stream = IPSearcher.class.getClassLoader().getResourceAsStream(DB_PATH);
            searcher = new DbSearcher(config, IoUtil.readBytes(stream));
        }
        catch (Exception e) {
            log.error("初始化DbSearcher异常:", e);
        }
        finally {
            if (null != stream) {
                try {  stream.close(); } catch (IOException e) {}
            }
        }
    }

    /***
     * 查询IP归属地
     * @param ip
     * @return
     */
    public static DataBlock ipRegin(String ip) {
        DataBlock dataBlock = null;
        int algorithm = DbSearcher.MEMORY_ALGORITYM;
        
        try {
            Method method = null;
            switch (algorithm) {
                case DbSearcher.BTREE_ALGORITHM:
                    method = searcher.getClass().getMethod("btreeSearch", String.class);
                    break;
                case DbSearcher.BINARY_ALGORITHM:
                    method = searcher.getClass().getMethod("binarySearch", String.class);
                    break;
                case DbSearcher.MEMORY_ALGORITYM:
                    method = searcher.getClass().getMethod("memorySearch", String.class);
                    break;
                default: break;
            }
            
            double sTime = 0, cTime = 0;
            sTime = System.nanoTime();
            dataBlock = (DataBlock) method.invoke(searcher, ip);
            cTime = (System.nanoTime() - sTime) / 1000000;
            log.info("%s in %.5f millseconds", dataBlock, cTime);
        }
        catch (NoSuchMethodException e) {
            log.error("IP 查询异常:", e);
        }
        catch (SecurityException e) {
            log.error("IP 查询异常:", e);
        }
        catch (IllegalAccessException e) {
            log.error("IP 查询异常:", e);
        }
        catch (IllegalArgumentException e) {
            log.error("IP 查询异常:", e);
        }
        catch (InvocationTargetException e) {
            log.error("IP 查询异常:", e);
        }
        catch (Exception e) {
            log.error("IP 查询异常:", e);
        }
        finally {
            if (null != searcher) {
                //try { searcher.close(); } catch (IOException e) {}
            }
        }

        return dataBlock;
    }

    public static void main(String[] argv) {
        ipRegin("223.243.128.2");
    }
}
