package com.system.scheduler;

import com.alibaba.fastjson.JSON;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.system.api.KingDeeApi;
import com.system.constants.Constants;
import com.system.constants.RsaKeyConstant;
import com.system.model.InitConnectParam;
import com.system.transfer.response.RestResponse;
import com.system.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Inori
 */
@Component
public class LicScheduler {

    private ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(5, new ThreadFactoryBuilder().setNameFormat("lic-pool-%d").build());

    private ScheduledFuture<?> scheduledFuture = null;

    public boolean flag = false;

    @Autowired
    private KingDeeApi kingDeeApi;

    @Autowired
    private RsaKeyConstant rsaKeyConstant;


    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    @PostConstruct
    public void init() {
        try {
            InitConnectParam initConnectParam = kingDeeApi.getInitConnectParam();
            if (StringUtil.isNotNull(initConnectParam)) {
                String data = initConnectParam.getLicCipherText();
                if (StringUtil.isNotBlank(data)) {
                    String result = RsaUtil.decryptByPublicKeyToLong(data, rsaKeyConstant.getPublicKey());
                    Map<String, String> map = JsonUtil.toMap(result, String.class, String.class);
                    if (!CollectionUtils.isEmpty(map) && map.containsKey(Constants.VERIFICATION_INTERVAL)) {
                        this.setLicScheduler(Integer.parseInt(map.get(Constants.VERIFICATION_INTERVAL)));
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setLicScheduler(Integer seconds) {
        if (StringUtil.isNotNull(scheduledFuture)) {
            scheduledFuture.cancel(false);
        }
        scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(new ScanScheduledExecutor(this, rsaKeyConstant.getPublicKey()), 1, seconds, TimeUnit.SECONDS);
    }

    static class ScanScheduledExecutor implements Runnable {

        private String publicKey;

        private LicScheduler licScheduler;


        public ScanScheduledExecutor(LicScheduler licScheduler, String publicKey) {
            this.publicKey = publicKey;
            this.licScheduler = licScheduler;
        }

        @Override
        public void run() {
            try {
                Map<String, Object> request = new HashMap<>(1);
                request.put("macAddress", LocalMacUtil.getLocalMac(InetAddress.getLocalHost()));
                request.put("source", "semiconductor");

                Map<String, Object> map = new HashMap<>(1);
                map.put("data", RsaUtil.encryptByPublicKeyToLong(JsonUtil.toString(request), publicKey));

                String result = HttpUtil.httpPost("https://lic.lingqingkeji.com:86/lic/api/lic/online/verification", JsonUtil.toString(map)).getBody();
                Map<String, Object> temp = JsonUtil.toMap(RsaUtil.decryptByPublicKeyToLong(result, publicKey), String.class, Object.class);

                if (!CollectionUtils.isEmpty(temp)) {
                    if (temp.containsKey(Constants.DATA_NAME) && StringUtil.isNotNull(temp.get(Constants.DATA_NAME))) {
                        String sign = String.valueOf(temp.get(Constants.DATA_NAME));
                        temp.put(Constants.DATA_NAME, new Object());

                        if (RsaUtil.verifySign(publicKey, JSON.toJSONString(temp), sign)) {
                            if (temp.containsKey(Constants.CODE_NAME)) {
                                licScheduler.setFlag(Integer.parseInt(String.valueOf(temp.get(Constants.CODE_NAME))) == RestResponse.CODE_SUCCESS);
                            } else {
                                licScheduler.setFlag(false);
                            }
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


}
