package com.crm.rely.backend.service.impl;

import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.SysCountryService;
import com.crm.rely.backend.util.*;
import com.google.common.base.Strings;
import lombok.extern.log4j.Log4j;
import net.renfei.ip2location.IP2Location;
import net.renfei.ip2location.IPResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;

@Log4j
@Service
public class SysCountryServiceImpl implements SysCountryService {

    private final static String ip2LocationLiteDb3DownloadUrl = "https://www.ip2location" +
            ".com/download/?token=Om92KAuv7E1Hb06YW5xucIC9dHyqo2yDAZdkKBcxTDVE32MXBn8VYfR3XtSadpez&file=DB3LITEBIN";
    private final static String ip2LocationLiteDb3DownloadName = "IP2LOCATION-LITE-DB3.BIN.ZIP";
    //名称
    private final static String ip2LocationLiteDb3 = "IP2LOCATION-LITE-DB3.BIN";
    private static String path = null;
    private static IP2Location loc = null;
    private static long time = 0;
    private static String yearMonth;
    private static String absolutePath = null;
    //路劲
    @Value("${ip.ip2LocationLiteDb3:../}")
    private String ip2LocationLiteDb3Child;

    private synchronized String getAbsolutePath() {
        if (Strings.isNullOrEmpty(absolutePath)) {
            File rootFile = new File("");
            File file = new File(rootFile.getAbsolutePath() + File.separator + ip2LocationLiteDb3Child);
            absolutePath = file.getPath();
        }
        return absolutePath;

    }

    @Scheduled(fixedDelay = 5 * 60 * 60 * 1000)
    private void scheduleDownload() throws Exception {
        String newYearMonth = DateUtil.format("yyyyMM");
        if (!newYearMonth.equals(yearMonth)) {
            yearMonth = newYearMonth;
            File file = new File(getPath(yearMonth));
            path = FileProcessUtil.getPath(getPath()).toString();
            if (!file.exists()) {

                //下载存放目录
                String targetDirectory =
                        getAbsolutePath() + File.separator + "download" + File.separator + yearMonth + File.separator + UUIDUtil.getUUID();
//                String targetDirectory =
//                        getAbsolutePath() + File.separator + "download" + File.separator + month;
                Path targetDirectoryPath = FileProcessUtil.getPath(targetDirectory);
                Files.createDirectories(targetDirectoryPath);
                targetDirectory = targetDirectoryPath.toString();
                //如果不存在 进行下载文件
                HttpUtil.download(ip2LocationLiteDb3DownloadUrl, targetDirectory,
                        ip2LocationLiteDb3DownloadName);
                //解压文件到指定目录
                ZipUtil.unzip(targetDirectory + File.separator + ip2LocationLiteDb3DownloadName,
                        FileProcessUtil.getPath(getAbsolutePath() + File.separator + yearMonth).toString());

                FileProcessUtil.deleteFile(targetDirectory);

            }
        }

    }

    private String getPath() {
        if (!Strings.isNullOrEmpty(path)) {
            return path;
        }
        return getPath(yearMonth);
    }

    private String getPath(String month) {
        path = getAbsolutePath() + File.separator + month + File.separator + ip2LocationLiteDb3;
        return path;
    }

    private synchronized IP2Location getIP2Location() {
        try {
            long nowTime = System.currentTimeMillis();
            if (loc == null || (nowTime - time) > 0) {
                if (loc != null) {
                    loc.Close();
                }
                loc = new IP2Location();
                String path = getPath();
                loc.Open(path, true);
                time = nowTime + 60 * 60 * 1000;

            }
            return loc;

        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        }
    }

    @Override
    public String getRequestByIp(HttpServletRequest request) throws ServiceException {
        return GetIpAndMac.getIp(request);
    }

    @Override
    public String getAdderByIp(String ip) throws ServiceException {

        StringBuffer adderS = new StringBuffer(20);
        adderS.append(ip);
        try {
            IP2Location loc = getIP2Location();
            if (loc == null) {
                return adderS.toString();
            }
            IPResult rec = loc.IPQuery(ip);
            if ("OK".equals(rec.getStatus())) {
                adderS.append("-");
                adderS.append(rec.getCountryLong());
                adderS.append("-");
                adderS.append(rec.getRegion());
                adderS.append("-");
                adderS.append(rec.getCity());
            } else if ("EMPTY_IP_ADDRESS".equals(rec.getStatus())) {
                System.out.println("IP address cannot be blank.");
            } else if ("INVALID_IP_ADDRESS".equals(rec.getStatus())) {
                System.out.println("Invalid IP address.");
            } else if ("MISSING_FILE".equals(rec.getStatus())) {
                System.out.println("Invalid database path.");
            } else if ("IPV6_NOT_SUPPORTED".equals(rec.getStatus())) {
                System.out.println("This BIN does not contain IPv6 data.");
            } else {
                System.out.println("Unknown error." + rec.getStatus());
            }
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace(System.out);
        }
        return adderS.toString();

    }

    @Override
    public String getCountryByIp(HttpServletRequest request) throws ServiceException {
        return getCountryByIp(getRequestByIp(request));
    }

    @Override
    public String getCountryByIp(String ip) throws ServiceException {
        StringBuffer adderS = new StringBuffer(20);
        try {
            IP2Location loc = getIP2Location();
            if (loc == null) {
                return adderS.toString();
            }
            IPResult rec = loc.IPQuery(ip);
            if ("OK".equals(rec.getStatus())) {
                adderS.append(rec.getCountryShort());
            } else if ("EMPTY_IP_ADDRESS".equals(rec.getStatus())) {
                System.out.println("IP address cannot be blank.");
            } else if ("INVALID_IP_ADDRESS".equals(rec.getStatus())) {
                System.out.println("Invalid IP address.");
            } else if ("MISSING_FILE".equals(rec.getStatus())) {
                System.out.println("Invalid database path.");
            } else if ("IPV6_NOT_SUPPORTED".equals(rec.getStatus())) {
                System.out.println("This BIN does not contain IPv6 data.");
            } else {
                System.out.println("Unknown error." + rec.getStatus());
            }
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace(System.out);
        }
        return adderS.toString();
    }

}
