package com.youchain.modules.license;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.json.JSONUtil;

import com.youchain.config.FileProperties;
import com.youchain.config.RsaProperties;
import com.youchain.exception.BadRequestException;
import com.youchain.modules.license.domain.LicenseCheck;
import com.youchain.utils.RsaUtils;
import com.youchain.utils.SpringContextHolder;
import com.youchain.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.codec.binary.Base64;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Date;


/**
 * @author 92525
 */
@Slf4j
public class LicenseValidate {

    public static LicenseCheck getKeyPrice() throws Exception{
        //读取本地文件
        FileProperties properties= SpringContextHolder.getBean(FileProperties.class);
        String result="";
        try{
            FileReader fileReader = new FileReader(properties.getPath().getPath()+"key/"+"license.key");
            result = fileReader.readString();

        }catch (Exception e){
            throw new BadRequestException("License不存在,请上传License");
        }

        String rsaResult= RsaUtils.decryptByPublicKey(RsaProperties.licenseKey,result);
        LicenseCheck keyPrice = JSONUtil.toBean(rsaResult, LicenseCheck.class);
        return keyPrice;
    }


    public static LicenseCheck getSystemPrice(){
        LicenseCheck licenseCheck=null;
        FileProperties properties= SpringContextHolder.getBean(FileProperties.class);
        String devicePath =properties.getPath().getPath()+"key/"+"device.key";
        String deviceInfoJson =readDeviceFile();
        if(StringUtils.isNotBlank(deviceInfoJson)){
            try{
                licenseCheck =JSONUtil.toBean(deviceInfoJson,LicenseCheck.class);
                BasicFileAttributes attributes = Files.readAttributes(Paths.get(devicePath), BasicFileAttributes.class);
                String  creationTime = attributes.creationTime().toString();
                String lastModifiedTime = attributes.lastModifiedTime().toString();
                Date licenseCheckDate = DateUtil.parse(licenseCheck.getCreateTime(), "yyyy-MM-dd");
                Date fCreationTime = DateUtil.parse(creationTime, "yyyy-MM-dd");
                Date fLastModifiedTime = DateUtil.parse(lastModifiedTime, "yyyy-MM-dd");

                long betweenDay = DateUtil.between(licenseCheckDate, fCreationTime, DateUnit.DAY);
                long betweenDay2 = DateUtil.between(licenseCheckDate, fLastModifiedTime, DateUnit.DAY);
                if(betweenDay==0&&betweenDay2==0){
                    //文件时间校验通过，不需要重新生成
                    return licenseCheck;
                }else{

                }

            }catch (Exception e){

            }
        }
        createDeviceFileOrRead();
        return licenseCheck;
    }

    public static void validate()  throws Exception{

        LicenseCheck keyPrice =getKeyPrice();

        LicenseCheck systemPrice = getSystemPrice();
        if(systemPrice==null){
            throw new BadRequestException("设备码异常");
        }

        if(keyPrice.getMainBoardSerial().equals(systemPrice.getMainBoardSerial())){

        }else{
            log.error("主板匹配失败");
            throw new BadRequestException("主板匹配失败");
        }
        if(keyPrice.getCpuSerial().equals(systemPrice.getCpuSerial())){

        }else{
            log.error("CPU匹配失败");
            throw new BadRequestException("CPU匹配失败");
        }

        try{
            Date endDate = DateUtil.parse(keyPrice.getEndTime());
            Date nowDate = DateUtil.date();

            if(endDate.before(nowDate)){
                throw new BadRequestException("过期的License,请重新生成");
            }else{

            }
        }catch (Exception e){
            throw new BadRequestException("无效的License,请重新生成");
        }
    }


    public static void saveCode(String licenseCode)  throws Exception{
        //读取本地文件
        log.error(licenseCode);
        String rsaResult="";
        try{
            rsaResult= RsaUtils.decryptByPublicKey(RsaProperties.licenseKey,licenseCode);
        }catch (Exception e){
            throw new BadRequestException("License无效，请重新生成");
        }

        //log.error(rsaResult);

        LicenseCheck keyPrice = JSONUtil.toBean(rsaResult, LicenseCheck.class);


        LicenseCheck systemPrice =getSystemPrice();


        if(keyPrice.getMainBoardSerial().equals(systemPrice.getMainBoardSerial())){
            log.error("主板匹配成功");
        }else{
            log.error("主板匹配失败");
            throw new BadRequestException("主板匹配失败");
        }
        if(keyPrice.getCpuSerial().equals(systemPrice.getCpuSerial())){
            log.error("CPU匹配成功");
        }else{
            log.error("CPU匹配失败");
            throw new BadRequestException("CPU匹配失败");
        }

        try{
            Date endDate = DateUtil.parse(keyPrice.getEndTime());
            Date nowDate = DateUtil.date();

            if(endDate.before(nowDate)){
                throw new BadRequestException("过期的License,请重新生成");
            }else{
                log.error("有效期验证通过");
            }
        }catch (Exception e){
            throw new BadRequestException("无效的License,请重新生成");
        }

        FileProperties properties= SpringContextHolder.getBean(FileProperties.class);

        FileWriter writer = new FileWriter(properties.getPath().getPath()+"key/"+"license.key");
        writer.write(licenseCode);

    }



    private static LicenseCheck getDeviceInfo(){
        String   osName = System.getProperty("os.name");
        osName = osName.toLowerCase();
        AGxServerInfos abstractServerInfos;
        //根据不同操作系统类型选择不同的数据获取方法
        if (osName.startsWith("windows")) {
            abstractServerInfos = new WindowsServerInfos();
        } else if (osName.startsWith("linux")) {
            abstractServerInfos = new LinuxServerInfos();
        }else{//其他服务器类型
            abstractServerInfos = new LinuxServerInfos();
        }
        return abstractServerInfos.getServerInfos();
    }




    public static String readDeviceFile(){
        FileProperties properties= SpringContextHolder.getBean(FileProperties.class);
        String path=properties.getPath().getPath()+"key/"+"device.key";
        try{
            FileReader fileReader=new FileReader(path);
            String jiaMiContent =fileReader.readString();
            String jieMi1= new String(Base64.decodeBase64(jiaMiContent));
            String jieMi2= new String(Base64.decodeBase64(jieMi1));
            return jieMi2;
        }catch (Exception e){
            log.error("设备码文件不存在");
            return "";
        }
    }

    public static  void createDeviceFileOrRead(){
        FileProperties properties= SpringContextHolder.getBean(FileProperties.class);
        String devicePath =properties.getPath().getPath()+"key/"+"device.key";
        System.out.println("获取配置文件路径："+devicePath);
        String deviceInfoJson =readDeviceFile();
        if(StringUtils.isNotBlank(deviceInfoJson)){
            try{
                LicenseCheck licenseCheck =JSONUtil.toBean(deviceInfoJson,LicenseCheck.class);
                BasicFileAttributes attributes = Files.readAttributes(Paths.get(devicePath), BasicFileAttributes.class);
                String  creationTime = attributes.creationTime().toString();
                String lastModifiedTime = attributes.lastModifiedTime().toString();
                System.out.println(creationTime+"-------------"+lastModifiedTime);
                Date licenseCheckDate = DateUtil.parse(licenseCheck.getCreateTime(), "yyyy-MM-dd");
                Date fCreationTime = DateUtil.parse(creationTime, "yyyy-MM-dd");
                Date fLastModifiedTime = DateUtil.parse(lastModifiedTime, "yyyy-MM-dd");

                long betweenDay = DateUtil.between(licenseCheckDate, fCreationTime, DateUnit.DAY);
                long betweenDay2 = DateUtil.between(licenseCheckDate, fLastModifiedTime, DateUnit.DAY);
                if(betweenDay==0&&betweenDay2==0){
                    //文件时间校验通过，不需要重新生成
                    System.out.println("------------------------文件时间校验通过，不需要重新生成-----------------------");
                    return ;
                }else{
                    System.out.println("------------------------文件时间校验失败，重新生成-----------------------");
                }

            }catch (Exception e){
                System.out.println("检验异常："+e.toString());
            }
        }
        //文件不存在，或者文件校验失败，删除文件，重新生成
        FileUtil.del(new File(devicePath));
        System.out.println("文件不存在，或者文件校验失败，删除文件，重新生成");

        LicenseCheck licenseCheck=getDeviceInfo();
        if(!StringUtils.isNotBlank(licenseCheck.getCpuSerial())){
            String cpuSerial=""+ (new java.util.Random().nextInt(89999999)+10000000);
            licenseCheck.setCpuSerial(cpuSerial);
        }
        if(!StringUtils.isNotBlank(licenseCheck.getMainBoardSerial())){
            String macSerial=""+ (new java.util.Random().nextInt(89999999)+10000000);
            licenseCheck.setMainBoardSerial(macSerial);
        }
        licenseCheck.setCreateTime(DateUtil.today());

        String rest= JSONUtil.toJsonStr(licenseCheck).trim();


        String jiaMi1 = Base64.encodeBase64String(rest.getBytes());
        String jiaMi2= Base64.encodeBase64String(jiaMi1.getBytes());

        FileWriter writer = new FileWriter(properties.getPath().getPath()+"key/"+"device.key");
        writer.write(jiaMi2);

    }

}
