package tech.easyflow.autoconfig.license;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.stereotype.Component;

/**
 * EasyFlow 启动前的 license 强制校验器。
 */
@Component
public class EasyflowLicenseBootstrapValidator implements BeanFactoryPostProcessor, EnvironmentAware, PriorityOrdered {

    private static final Logger LOG = LoggerFactory.getLogger(EasyflowLicenseBootstrapValidator.class);

    private final EasyflowLicenseVerifier easyflowLicenseVerifier;
    private String location;
    private String machineIdFile;
    private String productUuidFile;
    private String macAddressFile;

    /**
     * 构造启动前校验器。
     */
    public EasyflowLicenseBootstrapValidator() {
        this(null);
    }

    /**
     * 构造启动前校验器。
     *
     * @param easyflowLicenseVerifier license 校验器
     */
    EasyflowLicenseBootstrapValidator(EasyflowLicenseVerifier easyflowLicenseVerifier) {
        this.easyflowLicenseVerifier = easyflowLicenseVerifier;
    }

    /**
     * 从环境中读取 license 配置。
     *
     * @param environment Spring 环境
     */
    @Override
    public void setEnvironment(Environment environment) {
        this.location = environment.getProperty("easyflow.license.location");
        this.machineIdFile = environment.getProperty("easyflow.license.machine-id-file");
        this.productUuidFile = environment.getProperty("easyflow.license.product-uuid-file");
        this.macAddressFile = environment.getProperty("easyflow.license.mac-address-file");
    }

    /**
     * 在 BeanFactory 初始化阶段执行 license 校验。
     *
     * @param beanFactory BeanFactory
     * @throws BeansException 校验失败
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            EasyflowLicenseVerificationResult result = resolveVerifier().verify(location);
            LOG.info("license 校验通过: location={}, licenseId={}, keyId={}, licenseType={}, expiresAt={}",
                    result.location(),
                    result.licenseId(),
                    result.keyId(),
                    result.licenseType(),
                    result.expiresAt());
        } catch (EasyflowLicenseException ex) {
            if (ex.isMissing()) {
                LOG.error("lic 文件不存在: location={}, reason={}",
                        ex.getLocation(),
                        ex.getMessage(),
                        ex);
            } else {
                LOG.error("license 文件校验失败: location={}, licenseId={}, keyId={}, reason={}",
                        ex.getLocation(),
                        ex.getLicenseId(),
                        ex.getKeyId(),
                        ex.getMessage(),
                        ex);
            }
            throw new IllegalStateException(ex.getMessage(), ex);
        }
    }

    /**
     * 以最高优先级执行，先于其他启动扩展。
     *
     * @return 执行顺序
     */
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    private EasyflowLicenseVerifier resolveVerifier() {
        if (easyflowLicenseVerifier != null) {
            return easyflowLicenseVerifier;
        }
        DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
        MachineIdentityCollector collector = new MachineIdentityCollector(
                resourceLoader,
                machineIdFile,
                productUuidFile,
                macAddressFile
        );
        return new EasyflowLicenseVerifier(resourceLoader, collector);
    }
}
