package com.muyu.cloud.vehicle.gateway.aliyun.service;

import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.models.RuntimeOptions;
import com.muyu.cloud.vehicle.gateway.config.AliProperties;
import com.muyu.cloud.vehicle.gateway.domain.AliInstance;
import com.muyu.common.core.exception.ServiceException;
import com.muyu.common.redis.service.RedisService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 *ali业务层
 */
@Log4j2
@Service
public class AliYunEcsService {
    /**
     * 阿里云配置
     */
    @Autowired
    private AliProperties aliProperties;
    /**
     * 阿里云客户端
     */
    @Autowired
    private Client client;
    /**
     * redis缓存
     */
    @Autowired
    private RedisService redisService;

    /**
     * 生成实例
     *
     * @param amount 生成数量
     * @return 实例id集合
     */
    public List<String> generateInstance(Integer amount) {
        redisService.deleteObject("oneIpList");
        redisService.deleteObject("oneCount");
        redisService.deleteObject("oneVinIp");
        // 检查生成实例的数量是否有效
        if (amount == null || amount <= 0) {
            throw new ServiceException("生成数量不能小于1");
        }

// 初始化系统盘配置
        RunInstancesRequest.RunInstancesRequestSystemDisk systemDisk = new RunInstancesRequest.RunInstancesRequestSystemDisk();
        systemDisk.setSize("20");
        systemDisk.setCategory("cloud_essd");

// 创建创建实例请求对象并设置参数
        RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
                // 设置地域ID
                .setRegionId(aliProperties.getRegionId())
                // 设置镜像ID
                .setImageId(aliProperties.getImageId())
                // 设置实例规格类型
                .setInstanceType(aliProperties.getInstanceType())
                // 设置安全组ID
                .setSecurityGroupId(aliProperties.getSecurityGroupId())
                // 设置虚拟交换机ID
                .setVSwitchId(aliProperties.getSwitchId())
                // 设置实例名称
                .setInstanceName("server-mqtt")
                // 设置付费类型 按量付费
                .setInstanceChargeType("PostPaid")
                // 设置系统盘配置
                .setSystemDisk(systemDisk)
                // 设置用户名
                .setHostName("root")
                // 设置密码
                .setPassword("@ywt0219")
                // 设置要创建的实例数量
                .setAmount(amount)
                .setInternetChargeType("PayByTraffic")
                .setInternetMaxBandwidthOut(1);

        // 创建运行时选项对象
        RuntimeOptions runtimeOptions = new RuntimeOptions();

        // 尝试执行创建实例请求
        try {
            // 复制代码运行请自行打印 API 的返回值
            RunInstancesResponse runInstancesResponse = client.runInstancesWithOptions(runInstancesRequest, runtimeOptions);
            if (runInstancesResponse.getStatusCode() != 200) {
                throw new ServiceException("查询实例状态失败");
            }
            log.info("实例创建成功: {}", runInstancesResponse.getBody().getInstanceIdSets().instanceIdSet);
            RunInstancesResponseBody body = runInstancesResponse.getBody();
            RunInstancesResponseBody.RunInstancesResponseBodyInstanceIdSets instanceIdSets = body.getInstanceIdSets();
            return new ArrayList<>(instanceIdSets.instanceIdSet);
        } catch (Exception error) {
            log.error("创建阿里云实例报错：[{}]", error.getMessage());
            throw new ServiceException(error.getMessage());
        }
    }

    /**
     * 根据实例id查询实例信息
     *
     * @param instanceIds 实例id集合
     */
    public List<AliInstance> selectInstance(List<String> instanceIds) throws Exception {
        // 检查实例ID列表是否为空，如果为空则抛出异常
        if (instanceIds == null || instanceIds.isEmpty()) {
            throw new ServiceException("实例id不能为空");
        }
        // 创建查询实例的请求对象
        DescribeInstancesRequest request = new DescribeInstancesRequest()
                .setRegionId(aliProperties.getRegionId());

        // 创建运行时选项对象，用于配置请求的额外参数
        RuntimeOptions runtimeOptions = new RuntimeOptions();
        List<AliInstance> aliInstances = new ArrayList<>();
        List<String> stringArrayList = new ArrayList<>();
        try {
            // 发送请求并获取响应对象
            DescribeInstancesResponse describeInstancesResponse = client.describeInstancesWithOptions(request, runtimeOptions);
            // 检查响应状态码，如果为200则表示查询失败，抛出异常
            if (describeInstancesResponse.getStatusCode() != 200) {
                throw new ServiceException("查询实例状态失败");
            }
            List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> instance = describeInstancesResponse.getBody().getInstances().getInstance();
            for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance bodyInstance : instance) {
                // 实例id
                String instanceId = bodyInstance.getInstanceId();
                log.info("实例id为：{}", instanceId);
                // ip地址
                String ipAddress = bodyInstance.getPublicIpAddress().getIpAddress().get(0);
                log.info("实例ip为：{}", ipAddress);
                stringArrayList.add(ipAddress);
                // 实例状态
                String status = bodyInstance.getStatus();
                log.info("实例状态为：{}", status);
                AliInstance aliInstance = new AliInstance(instanceId, ipAddress, status);
                aliInstances.add(aliInstance);
                redisService.setCacheList(instanceId,aliInstances);
                aliInstances.remove(aliInstance);
            }
            log.info("======================ipList：{}",stringArrayList);
            redisService.setCacheList("oneIpList",stringArrayList);
            log.info("查询成功");
        } catch (Exception e) {
            log.error("查询服务器实例错误：[{}]", e.getMessage(), e);
            throw new RuntimeException(e);
        }
        return aliInstances;
    }

    /**
     * 删除实例
     */
    public void deleteInstance() throws Exception {
        DescribeInstancesRequest attributeRequest = new DescribeInstancesRequest();
        attributeRequest.setRegionId(aliProperties.getRegionId());

        RuntimeOptions runtimeOptions = new RuntimeOptions();

        DescribeInstancesResponse instancesWithOptions = client.describeInstancesWithOptions(attributeRequest, runtimeOptions);
        ArrayList<String> list = new ArrayList<>();
        DescribeInstancesResponseBody body = instancesWithOptions.getBody();
        for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : body.instances.instance) {
            list.add(instance.getInstanceId());
        }
        log.info("list:" + list);
        DeleteInstancesRequest deleteInstancesRequest = new DeleteInstancesRequest();
        deleteInstancesRequest.setRegionId(aliProperties.getRegionId())
                .setDryRun(false)
                .setForce(true)
                .setTerminateSubscription(true)
                .setInstanceId(list);
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            client.deleteInstancesWithOptions(deleteInstancesRequest, runtime);
        } 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);
        }
    }
}
