/*
 * 文 件 名:  DeviceCallServiceImpl
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  <描述>
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/2/26
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.ruoyi.ems.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.huashe.common.exception.Assert;
import com.huashe.common.exception.BusinessException;
import com.ruoyi.ems.domain.EmsObjAbility;
import com.ruoyi.ems.domain.EmsObjModel;
import com.ruoyi.ems.model.AbilityPayload;
import com.ruoyi.ems.model.CallResponse;
import com.ruoyi.ems.service.IAbilityCallService;
import com.ruoyi.ems.service.IEmsObjModelService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 设备调用服务
 * <功能详细描述>
 *
 * @author lvwenbin
 * @version [版本号, 2025/2/26]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Service
public class AbilityCallServiceImpl implements IAbilityCallService {
    private static final Logger log = LoggerFactory.getLogger(AbilityCallServiceImpl.class);

    @Autowired
    private IEmsObjModelService objModelService;

    @Override
    public String devAbilityCall(AbilityPayload payload) {
        String ret = null;

        try {
            Assert.notNull(payload.getObjCode(), -1, "对象代码code不能为空");
            Assert.notNull(payload.getAbilityKey(), -1, "设备模型能力key不能为空");

            EmsObjModel objModel = objModelService.selectByModelCode(payload.getModelCode());
            Assert.notNull(objModel, -1, "设备模型（" + payload.getModelCode() + "）不存在");
            payload.setObjType(objModel.getObjType());

            Assert.notNull(objModel.getAbilityHandler(), -1, "设备模型处理Handler未配置");

            List<EmsObjAbility> objAbilitys = objModel.getAbilityList();
            Assert.isTrue(checkExist(payload.getAbilityKey(), objAbilitys), -1,
                "设备模型（" + payload.getModelCode() + "）能力（" + payload.getAbilityKey() + "）不存在");

            String jsonBody = JSON.toJSONString(payload);

            String res = execPost(objModel.getAbilityHandler(), jsonBody);
            CallResponse<?> callResponse = JSONObject.parseObject(res, CallResponse.class);
            Assert.isTrue(callResponse.getCode() == 0, -1, callResponse.getMessage());
            ret = callResponse.getMessage();
        }
        catch (BusinessException e) {
            log.info("调用设备模型能力执行失败! {}", e.getMessage());
            throw e;
        }
        catch (Exception e) {
            log.info("调用设备模型能力执行失败!", e);
            throw new BusinessException(e.getMessage(), e);
        }

        return ret;
    }

    private String execPost(String url, String jsonBody) {
        log.info("execPost [request] url:{} \njsonBody:\n{}", url, jsonBody);

        String responseBody = null;

        // 使用try-with-resources自动关闭HttpClient和Response
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 创建POST请求并设置URL
            HttpPost httpPost = new HttpPost(url);

            // 构造JSON请求体
            StringEntity requestEntity = new StringEntity(jsonBody, ContentType.APPLICATION_JSON);
            httpPost.setEntity(requestEntity);

            // 执行请求并处理响应
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                // 获取状态码
                int statusCode = response.getStatusLine().getStatusCode();
                System.out.println("Status Code: " + statusCode);

                // 获取响应内容
                responseBody = EntityUtils.toString(response.getEntity());
                log.info("execPost [response] statusCode:{} \nresponseBody:\n{}", statusCode, responseBody);
            }
        }
        catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }

        return responseBody;
    }

    private boolean checkExist(String abilityKey, List<EmsObjAbility> objAbilitys) {
        for (EmsObjAbility objAbility : objAbilitys) {
            if (StringUtils.equals(abilityKey, objAbility.getAbilityKey())) {
                return true;
            }
        }

        return false;
    }
}