package com.fdkankan.rubbersheeting;

import com.alibaba.fastjson.JSON;
import com.aliyun.ess20220222.models.ExecuteScalingRuleRequest;
import com.aliyun.ess20220222.models.ExecuteScalingRuleResponse;
import com.aliyun.ess20220222.models.RemoveInstancesRequest;
import com.aliyun.ess20220222.models.RemoveInstancesResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.DescribeInstancesRequest;
import com.aliyuncs.ecs.model.v20140526.DescribeInstancesResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.fdkankan.common.util.OkHttpUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Hb_zzZ on 2020/8/25.
 */
@Slf4j
@Component
@ConditionalOnProperty(name = "scaling.type",havingValue = "oss")
@Data
public class AliYunScalingService implements ScalingService{

    @Value("${scaling.group.id}")
    private String scalingGroupId;

    @Value("${scaling.rule.ari}")
    private String scalingRuleAri;

    @Value("${scaling.accessKeyId:#{null}}")
    private String accessKeyId;

    @Value("${scaling.accessKeySecret:#{null}}")
    private String accessKeySecret;

    @Value("${scaling.endPoint:ess.aliyuncs.com}")
    public String endPoint;

    public static com.aliyun.ess20220222.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // Endpoint 请参考 https://api.aliyun.com/product/Ess
        config.endpoint = "ess.aliyuncs.com";
        return new com.aliyun.ess20220222.Client(config);
    }

    public static void main(String[] args_) throws Exception {

//        AliYunScalingService aliYunScalingService = new AliYunScalingService();
////        aliYunScalingService.setScalingGroupId("asg-wz918td5gc2qcdx2de7q");
//        aliYunScalingService.setScalingRuleAri("ari:acs:ess:cn-shenzhen:1899912233141089:scalingrule/asr-wz97gv4s2nod1cxznynx");
//        aliYunScalingService.setAccessKeyId("LTAI4GKZQBM1zZZZBJK7nGjR");
//        aliYunScalingService.setAccessKeySecret("bo1ura8KODXASVyZ5fofy0fWFILumz&");
//        final String ecs = aliYunScalingService.createEcs(aliYunScalingService.getScalingRuleAri());
//        System.out.println(ecs);

//        // 初始化阿里云客户端
//        DefaultProfile profile = DefaultProfile.getProfile(
//                "oss-cn-shenzhen",          // 如 cn-hangzhou
//                "LTAI4GKZQBM1zZZZBJK7nGjR",      // AccessKeyId
//                "bo1ura8KODXASVyZ5fofy0fWFILumz&"); // AccessKeySecret
//        IAcsClient client = new DefaultAcsClient(profile);
//
//        // 指定伸缩组ID
//        String scalingGroupId = "<您的伸缩组ID>";
//
//        try {
//            // 创建扩容请求
//            ExecuteScalingActionRequest request = new ExecuteScalingActionRequest();
//            request.setScalingGroupId(scalingGroupId);
//            request.setScalingAction("SCALE_OUT"); // 执行扩容动作
//
//            // 根据伸缩组配置自动创建实例
//            ExecuteScalingActionResponse response = client.getAcsResponse(request);
//
//            // 输出响应信息（可根据需求处理）
//            System.out.println(response.getRequestId());
//
//        } catch (ClientException e) {
//            e.printStackTrace();
//        }

        java.util.List<String> args = java.util.Arrays.asList(args_);
        // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用，仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html
        com.aliyun.ess20220222.Client client = AliYunScalingService.createClient(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        com.aliyun.ess20220222.models.AttachInstancesRequest tagResourcesRequest = new com.aliyun.ess20220222.models.AttachInstancesRequest()
                .setRegionId("your_value")
                .setScalingGroupId("your_value");
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.attachInstances(tagResourcesRequest);
        } catch (TeaException error) {
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        }

    }

    private String sign(String action, Map<String, String> parameters) throws Exception{
        final String HTTP_METHOD = "GET";

        final String ALGORITHM = "HmacSHA1";
        final String ENCODING = "UTF-8";

        // 对参数进行排序
        String[] sortedKeys = parameters.keySet().toArray(new String[]{});
        Arrays.sort(sortedKeys);

        final String SEPARATOR = "&";

        // 生成stringToSign字符串
        StringBuilder stringToSign = new StringBuilder();
        stringToSign.append(HTTP_METHOD).append(SEPARATOR);
        stringToSign.append(percentEncode("/")).append(SEPARATOR);

        StringBuilder canonicalizedQueryString = new StringBuilder();
        for(String key : sortedKeys) {
            // 这里注意对key和value进行编码
            canonicalizedQueryString.append("&").append(percentEncode(key)).append("=").append(percentEncode(parameters.get(key)));
        }

        // 这里注意对canonicalizedQueryString进行编码
        stringToSign.append(percentEncode(canonicalizedQueryString.toString().substring(1)));

        Mac mac = Mac.getInstance(ALGORITHM);
        mac.init(new SecretKeySpec(accessKeySecret.getBytes(ENCODING), ALGORITHM));
        byte[] signData = mac.doFinal(stringToSign.toString().getBytes(ENCODING));

        String signature = new String(org.apache.commons.codec.binary.Base64.encodeBase64(signData));
        return signature;
    }

    private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    private static String formatIso8601Date(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
        df.setTimeZone(new SimpleTimeZone(0, "GMT"));
        return df.format(date);
    }

    private static final String ENCODING = "UTF-8";

    private static String percentEncode(String value) throws UnsupportedEncodingException {
        return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
    }

    @Override
    public String createEcs(){
        return this.createEcs(scalingRuleAri);
    }

    @Override
    public String createEcs(String ruleAri) {
        return this.createEcsByConfig(ruleAri);
    }

    @Override
    public String createEcsByConfig(Map<String, String> configs) {
        String ruleAri = configs.get("ruleAri");
        return this.createEcsByConfig(ruleAri);
    }

    @Override
    public String createEcsByConfig(String ruleAri) {

        com.aliyun.teaopenapi.models.Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(accessKeySecret);
        config.setEndpoint(endPoint);

//        IAcsClient client = new DefaultAcsClient(profile);
        com.aliyun.ess20220222.Client client = null;
        try {
            client = new com.aliyun.ess20220222.Client(config);
        } catch (Exception e) {
            log.error("创建弹性伸缩客户端异常", e);
        }

        // 创建API请求并设置参数
        ExecuteScalingRuleRequest executeScalingRuleRequest = new ExecuteScalingRuleRequest();
        executeScalingRuleRequest.setScalingRuleAri(ruleAri);

        // 发起请求并处理应答或异常
        ExecuteScalingRuleResponse executeScalingRuleResponse = null;
        try {
            executeScalingRuleResponse = client.executeScalingRule(executeScalingRuleRequest);
            return JSON.toJSONString(executeScalingRuleResponse);
        } catch (Exception e) {
            log.error("触发弹性伸缩规则异常", e);
        }

        return "启动弹性伸缩失败";
    }

    @Override
    public  String deleteEcs(String id){
        return this.deleteEcs(scalingGroupId, id);
    }

    @Override
    public  String deleteEcs(String groupId, String instanceId){
        com.aliyun.teaopenapi.models.Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(accessKeySecret);
        config.setEndpoint(endPoint);

//        IAcsClient client = new DefaultAcsClient(profile);
        com.aliyun.ess20220222.Client client = null;
        try {
            client = new com.aliyun.ess20220222.Client(config);
        } catch (Exception e) {
            log.error("创建弹性伸缩客户端异常", e);
        }

        // 创建API请求并设置参数
        RemoveInstancesRequest removeInstancesRequest = new RemoveInstancesRequest();
        removeInstancesRequest.setScalingGroupId(groupId);
        removeInstancesRequest.setInstanceIds(Arrays.asList(instanceId));

        // 发起请求并处理应答或异常
        RemoveInstancesResponse removeInstancesResponse = null;
        try {
            removeInstancesResponse = client.removeInstances(removeInstancesRequest);
            return JSON.toJSONString(removeInstancesResponse);
        } catch (Exception e) {
            log.error("触发弹性伸缩规则异常", e);
        }

        return "移除弹性伸缩实例失败";
    }

}
