package com.qmth.boot.api.config;

import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.core.enums.Platform;
import com.qmth.boot.core.rateLimit.annotation.RateLimit;
import com.qmth.boot.core.rateLimit.entity.RateLimitRule;
import com.qmth.boot.tools.signature.SignatureType;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class ApiConfig {

    public static final String[] EMPTY_STRING_ARRAY = new String[] {};

    public static final Platform[] EMPTY_PLATFORM_ARRAY = new Platform[] {};

    public static final SignatureType[] EMPTY_SIGNATURE_TYPE = new SignatureType[] {};

    private Boolean strict;

    private Platform[] platform = EMPTY_PLATFORM_ARRAY;

    private String[] ipAllow = EMPTY_STRING_ARRAY;

    private String[] ipDeny = EMPTY_STRING_ARRAY;

    private List<RateLimitRule> rateLimit = Collections.emptyList();

    private Boolean auth;

    private SignatureType[] signType = EMPTY_SIGNATURE_TYPE;

    public ApiConfig(ApiProperties properties) {
        this.strict = properties.isGlobalStrict();
        this.auth = properties.isGlobalAuth();
        //全局限流配置
        buildRateLimitRule(properties.getGlobalRateLimit());
    }

    public ApiConfig(Aac annotation) {
        if (annotation == null) {
            return;
        }
        if (annotation.strict().length > 0) {
            this.strict = annotation.strict()[0];
        }
        if (annotation.platform().length > 0) {
            this.platform = annotation.platform();
        }
        if (annotation.auth().length > 0) {
            this.auth = annotation.auth()[0];
        }
        if (annotation.ipAllow().length > 0) {
            this.ipAllow = annotation.ipAllow();
        }
        if (annotation.ipDeny().length > 0) {
            this.ipDeny = annotation.ipDeny();
        }
        if (annotation.signType().length > 0) {
            this.signType = annotation.signType();
        }

        buildRateLimitRule(annotation.rateLimit());
    }

    public void merge(ApiConfig config) {
        if (config == null) {
            return;
        }
        if (config.strict != null) {
            this.strict = config.strict;
        }
        if (ArrayUtils.isNotEmpty(config.platform)) {
            this.platform = config.platform;
        }
        if (config.auth != null) {
            this.auth = config.auth;
        }
        if (ArrayUtils.isNotEmpty(config.ipAllow)) {
            this.ipAllow = config.ipAllow;
        }
        if (ArrayUtils.isNotEmpty(config.ipDeny)) {
            this.ipDeny = config.ipDeny;
        }
        if (ArrayUtils.isNotEmpty(config.signType)) {
            this.signType = config.signType;
        }
        if (!CollectionUtils.isEmpty(config.rateLimit)) {
            this.rateLimit = config.rateLimit;
        }
    }

    public boolean isStrict() {
        return strict;
    }

    public Platform[] getPlatform() {
        return platform;
    }

    public String[] getIpAllow() {
        return ipAllow;
    }

    public String[] getIpDeny() {
        return ipDeny;
    }

    public List<RateLimitRule> getRateLimit() {
        return rateLimit;
    }

    public boolean isAuth() {
        return auth;
    }

    public SignatureType[] getSignType() {
        return signType;
    }

    private void buildRateLimitRule(RateLimit[] annotations) {
        if (ArrayUtils.isNotEmpty(annotations)) {
            this.rateLimit = Arrays.stream(annotations).map(RateLimitRule::parse).collect(Collectors.toList());
        }
    }

    private void buildRateLimitRule(String[] ratelimitArray) {
        if (ArrayUtils.isNotEmpty(ratelimitArray)) {
            this.rateLimit = Arrays.stream(ratelimitArray).map(RateLimitRule::parse).collect(Collectors.toList());
        }
    }
}
