package com.ema.common.tools.ip2region.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.ema.common.domain.vo.IPVo;
import com.ema.common.exceptions.MyAssert;
import com.ema.common.tools.ip2region.IP2RegionService;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.List;

@Slf4j
@Service
public class IP2RegionServiceImpl implements IP2RegionService {

    private static final Searcher searcher = initialize();

    private static Searcher initialize() {
        try {
            if (searcher == null) {
                //复制到临时文件再加载
                ClassPathResource resource = new ClassPathResource("ip2region.xdb");
                File tempFile = File.createTempFile("ip2region", ".xdb");
                Files.copy(resource.getInputStream(), tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                return Searcher.newWithFileOnly(tempFile.getAbsolutePath());
            }
        } catch (IOException e) {
            log.error("初始化加载 ip2region 失败。{}", e.getMessage());
        }
        return null;
    }


    /**
     * 获取IP位置，
     * 只有中国的数据精确到了城市，其他国家有部分数据只能定位到国家
     *
     * @param ips
     * @return
     */
    @Override
    public List<IPVo> getIPLocation(List<String> ips) {
        List<IPVo> voList = CollUtil.toList();
        ips = CollUtil.distinct(ips);
        for (String ip : ips) {
            if (StrUtil.isNotBlank(ip)) {
                IPVo vo = getIPLocation(ip);
                if (vo != null) {
                    voList.add(vo);
                }
            }
        }
        return voList;
    }

    /**
     * 获取IP位置，
     * 只有中国的数据精确到了城市，其他国家有部分数据只能定位到国家
     *
     * @param ip
     * @return
     */
    @Override
    public IPVo getIPLocation(String ip) {
        try {
            MyAssert.notNull(searcher, "ip2region.xdd 数据文件不存在。");
            ip = StrUtil.trimToNull(ip);
            if (StrUtil.isNotBlank(ip)) {  //是否是有效IP
                String region = searcher.search(ip);
                if (StrUtil.isNotBlank(region)) {
                    return new IPVo(ip, region);
                }
            }
        } catch (Exception e) {
            log.error("IP定位查询失败：{}", e.getMessage());
        }
        return null;
    }


}
