package com.huashe.park.collect.config;

import java.util.List;
import java.util.Map;

import com.alibaba.fastjson2.JSONObject;
import com.huashe.common.utils.StringUtils;
import com.huashe.park.common.ByteArrayUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import lombok.Getter;
import lombok.Setter;

@Configuration
@ConfigurationProperties(value = "aliyun")

public class TopicDataCfg {
    private TopicData resultTopic;

    private TopicData processTopic;

    public TopicData getResultTopic() {
        return resultTopic;
    }

    public void setResultTopic(TopicData resultTopic) {
        this.resultTopic = resultTopic;
    }

    public TopicData getProcessTopic() {
        return processTopic;
    }

    public void setProcessTopic(TopicData processTopic) {
        this.processTopic = processTopic;
    }

    @Getter
    @Setter
    public static class TopicData {
        private Map<String, TopicDataCfg.Protocol> protocol;

        private String name;
    }

    @Getter
    @Setter
    public static class Protocol {
        private String type;

        private List<Integer> range;

        private String byteSort = "little";
    }

    public JSONObject byteFormat(byte[] payload, Map<String, TopicDataCfg.Protocol> protocolMap) {
        JSONObject jsonObject = new JSONObject();
        protocolMap.forEach((key, value) -> {
            String camelCase = StringUtils.toCamelCase(key);
            switch (value.getType()) {
                case "short":
                    if (value.getByteSort().equals("big")) {
                        jsonObject.put(camelCase, ByteArrayUtil.byteArray2Short_Big_Endian(
                                getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                        break;
                    }
                    jsonObject.put(camelCase, ByteArrayUtil.byteArray2Short_Little_Endian(
                            getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                    break;
                case "byte":
                    jsonObject.put(camelCase, getByteArray(payload, value.getRange().get(0), value.getRange().get(1)));
                    break;
                case "long":
                    if (value.getByteSort().equals("big")) {
                        jsonObject.put(camelCase, ByteArrayUtil.byteArray2Long_Big_Endian(
                                getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                        break;
                    }
                    jsonObject.put(camelCase, ByteArrayUtil.byteArray2Long_Little_Endian(
                            getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                    break;
                case "int":
                    if (value.getByteSort().equals("big")) {
                        jsonObject.put(camelCase, ByteArrayUtil.byteArray2Int_Big_Endian(
                                getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                        break;
                    }
                    jsonObject.put(camelCase, ByteArrayUtil.byteArray2Int_Little_Endian(
                            getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                    break;
                case "double":
                    if (value.getByteSort().equals("big")) {
                        jsonObject.put(camelCase, ByteArrayUtil.byteArray2Double_Big_Endian(
                                getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                        break;
                    }
                    jsonObject.put(camelCase, ByteArrayUtil.byteArray2Double_Little_Endian(
                            getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                    break;
                case "float":
                    if (value.getByteSort().equals("big")) {
                        jsonObject.put(camelCase, ByteArrayUtil.byteArray2Float_Big_Endian(
                                getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                        break;
                    }
                    jsonObject.put(camelCase, ByteArrayUtil.byteArray2Float_Little_Endian(
                            getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                    break;
                case "string":
                    if (value.getRange().isEmpty()) {
                        break;
                    }
                    if (value.getRange().size() > 1) {
                        jsonObject.put(camelCase,
                                new String(getByteArray(payload, value.getRange().get(0), value.getRange().get(1))));
                        break;
                    }
                    jsonObject.put(camelCase,
                            new String(getByteArray(payload, value.getRange().get(0), payload.length - 1)));
                    break;
                default:
                    break;
            }
        });
        return jsonObject;
    }

    private byte[] getByteArray(byte[] payload, Integer startIncludeIndex, Integer endIncludeIndex) {
        return ArrayUtils.subarray(payload, startIncludeIndex, endIncludeIndex + 1);
    }

}
