package com.njcn.roma.controller;

import cn.hutool.crypto.digest.DigestUtil;
import com.njcn.roma.pojo.CommandDTO;
import com.njcn.roma.pojo.UpSendPojo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Objects;

/**
 * roma
 *
 * @author cdf
 * @date 2024/6/25
 */
@RestController
@RequestMapping("send")
@RequiredArgsConstructor
public class SendCommandController {

    @Value("${roma.acceptIp}")
    private String acceptIp;

    @Value("${roma.sendIp}")
    private String sendIp;

    @Value("${roma.appId}")
    private String appId;

    @Value("${roma.appKey}")
    private String appKey;

    private final RestTemplate restTemplate;

    /**
     * 测试下发程序
     * @author cdf
     * @date 2024/6/25
     */
    @GetMapping("up")
    public String sendToDev(@RequestParam("serviceId")String serviceId,@RequestParam("method")String method,@RequestParam(value = "deviceId",defaultValue = "D2899233167kupZT")String deviceId){
        org.json.JSONObject commandContent = new JSONObject();
        commandContent.put("status", "on");
        try {
            deviceCommands(deviceId,serviceId,method,commandContent);
        } catch (IOException e) {
            System.out.println("IOException---------------------------");
            e.printStackTrace();
            return e.getMessage();
        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException---------------------------");
            e.printStackTrace();
            return e.getMessage();
        } catch (KeyStoreException e) {
            System.out.println("KeyStoreException---------------------------");
            e.printStackTrace();
            return e.getMessage();
        } catch (KeyManagementException e) {
            System.out.println("KeyManagementException---------------------------");
            e.printStackTrace();
            return e.getMessage();
        }catch (Exception e){
            System.out.println("Exception---------------------------");
            e.printStackTrace();
            return e.getMessage();
        }
        return "执行成功";
    }






    @GetMapping("queryService")
    public String test(@RequestParam(value = "deviceId",defaultValue = "D2899233167kupZT")String deviceId){
        //String url = "https://" + sendIp + "/iot/1.0/deviceCommands?appId=" + appId;

        String url = "https://" + sendIp + "/iot/1.0/services?appId=" + appId+"&deviceId="+deviceId;
        HttpGet httpGet = new HttpGet(url);  //创建post请求
        setSSLHeader(httpGet);	//设置请求的header
        try {
            org.apache.http.HttpEntity responseEntity = getSSLResponse(httpGet);//获取响应结果
            return EntityUtils.toString(responseEntity);
        } catch (IOException e) {
            System.out.println("IOException---------------------------");
            e.printStackTrace();
            return e.getMessage();
        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException---------------------------");
            e.printStackTrace();
            return e.getMessage();
        } catch (KeyStoreException e) {
            System.out.println("KeyStoreException---------------------------");
            e.printStackTrace();
            return e.getMessage();
        } catch (KeyManagementException e) {
            System.out.println("KeyManagementException---------------------------");
            e.printStackTrace();
            return e.getMessage();
        }catch (Exception e){
            System.out.println("Exception---------------------------");
            e.printStackTrace();
            return e.getMessage();
        }
    }


    /**
     * 创建ssl连接，设置客户端信任所有证书
     * @return CloseableHttpClient
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    private CloseableHttpClient createSSLClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }

    /**
     * 设置请求时的header
     * @param httpUriRequest
     */
    private void setSSLHeader(HttpUriRequest httpUriRequest) {
        long time = System.currentTimeMillis();
        String authorization = DigestUtils.sha256Hex(appId + appKey + time);
        httpUriRequest.addHeader("Content-Type", "application/json");
        httpUriRequest.addHeader("Authorization", authorization);
        httpUriRequest.addHeader("timestamp", String.valueOf(time));
    }
    /**
     * 解析响应结果
     * @param httpUriRequest
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws KeyManagementException
     * @throws IOException
     */
    private org.apache.http.HttpEntity getSSLResponse(HttpUriRequest httpUriRequest) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
        CloseableHttpClient httpClient = createSSLClient();
        CloseableHttpResponse response = httpClient.execute(httpUriRequest);
        org.apache.http.HttpEntity responseEntity = response.getEntity();
        System.out.println("响应状态为:" + response.getStatusLine());
        if (responseEntity != null) {
            System.out.println("响应内容长度为:" + responseEntity.getContentLength());
            System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
        }
        return responseEntity;
    }

    /**
     * 命令下发
     *
     * @param serviceName
     * @param commandName
     * @param cmdComtent
     * @throws JSONException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws KeyManagementException
     */
    public void deviceCommands(String deviceId,String serviceName, String commandName, org.json.JSONObject cmdComtent) throws JSONException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        String url = "https://" + sendIp + "/iot/1.0/deviceCommands?appId=" + appId;
        HttpPost httpPost = new HttpPost(url);  //创建post请求

        org.json.JSONObject cmdContent = new org.json.JSONObject();
        cmdContent.put("serviceId", serviceName);
        cmdContent.put("method", commandName);
        cmdContent.put("paras", cmdComtent);
        org.json.JSONObject cmdBody = new org.json.JSONObject();
        cmdBody.put("command", cmdContent);
        cmdBody.put("deviceId", deviceId);

        setSSLHeader(httpPost);	//设置请求的header
        StringEntity stringEntity = new StringEntity(cmdBody.toString(), "utf-8");
        httpPost.setEntity(stringEntity);//设置请求的body
        getSSLResponse(httpPost);//获取响应结果

    }
}
