package com.qmth.boot.core.solar.service;

import com.qmth.boot.core.solar.api.SolarApiClient;
import com.qmth.boot.core.solar.config.SolarProperties;
import com.qmth.boot.core.solar.crypto.AppLicenseUtil;
import com.qmth.boot.core.solar.model.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;

@Component
public class SolarService {

    private static final Logger log = LoggerFactory.getLogger(SolarService.class);

    private SolarProperties solarProperties;

    private SolarApiClient solarApiClient;

    private AppLicense license;

    private AppInfo appInfo;

    public SolarService(SolarProperties solarProperties, SolarApiClient solarApiClient) {
        this.solarProperties = solarProperties;
        this.solarApiClient = solarApiClient;
        checkup();
    }

    /**
     * 获取应用部署信息
     *
     * @return
     */
    public AppInfo getAppInfo() {
        return appInfo;
    }

    /**
     * 获取应用控制参数
     *
     * @return
     */
    public AppControl getAppControl() {
        return appInfo != null ? appInfo.getControl() : null;
    }

    /**
     * 获取当前应用可以访问的机构集合，自动判断在线/离线激活两种模式
     *
     * @return
     */
    public List<OrgInfo> getOrgList() {
        if (license != null) {
            //offline
            return license.getOrgs();
        } else {
            //online
            List<OrgInfo> list = new LinkedList<>();
            int pageNumber = 1;
            int pageSize = 20;
            while (true) {
                List<OrgInfo> page = solarApiClient.listOrgInfo(pageNumber, pageSize);
                if (page == null || page.isEmpty()) {
                    break;
                }
                list.addAll(page);
                pageNumber++;
            }
            return list;
        }
    }

    /**
     * 使用AK信息在线激活
     *
     * @param accessKey
     * @param accessSecret
     * @return
     */
    public synchronized AppInfo update(String accessKey, String accessSecret) {
        appInfo = null;
        license = null;
        solarProperties.setAccessKey(accessKey);
        solarProperties.setAccessSecret(accessSecret);
        solarProperties.setLicense(null);
        try {
            AppInfo info = solarApiClient.getAppInfo();
            if (info != null && checkAppCode(info)) {
                appInfo = info;
            }
        } catch (Exception e) {
            log.error("Solar api invoke error", e);
        }
        return appInfo;
    }

    /**
     * 使用授权文件离线激活，同时需要在有效期内
     *
     * @param licenseData
     * @return
     */
    public synchronized AppInfo update(byte[] licenseData) {
        appInfo = null;
        license = null;
        solarProperties.setAccessKey(null);
        solarProperties.setAccessSecret(null);
        AppLicense result = AppLicenseUtil
                .parseLicense(licenseData, StringUtils.trimToEmpty(solarProperties.getAppVersion()));
        if (result != null && checkAppCode(result) && !result.getControl().hasExpired()) {
            license = result;
            appInfo = result;
        }
        return appInfo;
    }

    private boolean checkAppCode(AppInfo info) {
        return StringUtils.isBlank(solarProperties.getAppCode()) || solarProperties.getAppCode()
                .equalsIgnoreCase(info.getCode());
    }

    private void checkup() {
        log.info("Solar startup checking...");
        if (StringUtils.isNotBlank(solarProperties.getAccessKey()) && StringUtils
                .isNotBlank(solarProperties.getAccessSecret())) {
            try {
                AppInfo info = solarApiClient.getAppInfo();
                if (info != null && checkAppCode(info)) {
                    appInfo = info;
                }
            } catch (Exception e) {
                log.error("Solar api invoke error", e);
            }
        } else if (StringUtils.isNotBlank(solarProperties.getLicense())) {
            //启动授权文件默认绑定硬件信息
            AppLicense license = AppLicenseUtil.parseLicense(solarProperties.getLicense(),
                    StringUtils.trimToEmpty(solarProperties.getAppVersion()));
            if (license != null) {
                if (!checkAppCode(license)) {
                    log.error("Solar license appCode invalid");
                } else if (license.getControl().hasExpired()) {
                    log.error("Solar license has expired");
                } else {
                    this.license = license;
                    this.appInfo = license;
                }
            }
        } else {
            log.warn("Solar startup check exit, accessKey&accessSecret and license file not exist!");
        }
        if (appInfo != null) {
            log.info("Solar startup check success, current appname={}", appInfo.getName());
        } else {
            log.info("Solar startup check faile!");
        }
    }

    /**
     * 根据appId获取微信访问令牌
     *
     * @param appId
     * @return
     */
    public WxappAccessToken getWxappAccessToken(String appId) {
        return solarApiClient.getWxappAccessToken(appId);
    }

    /**
     * 通过appId及临时凭证获取微信登录密钥接口
     *
     * @param appId
     * @param code
     * @return
     */
    public WxappSession getWxappSessionByCode(String appId, String code) {
        return solarApiClient.getWxappSessionByCode(appId, code);
    }

    /**
     * 通过appId及手机号快速验证code获取真实手机号
     *
     * @param appId
     * @param code
     * @return
     */
    public WxappPhoneNumber getWxappPhoneNumber(String appId, String code) {
        return solarApiClient.getWxappPhoneNumber(appId, code);
    }

}
