package net.northking.cctp.upperComputer.driver.usbmuxd.payload.usbmuxd.entity;

import com.dd.plist.NSDictionary;
import com.dd.plist.NSNumber;
import com.dd.plist.NSString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 苹果设备连接详情<br>
 * 所有成员均不为null
 */
public class DeviceConnectionDetail {
    private Logger logger = LoggerFactory.getLogger(DeviceConnectionDetail.class);
    /**
     * 设备在usbmuxd上的id<br>
     * 基础信息，来自usbmuxd
     */
    public final int deviceId;

    /**
     * 连接带宽（bit）<br>
     * 基础信息，来自usbmuxd
     */
    public final long connectionSpeed;

    /**
     * 连接状态<br>
     * 基础信息，来自usbmuxd
     */
    public final ConnectStatus connectStatus;

    /**
     * 设备连接usbmuxd的方式<br>
     * 基础信息，来自usbmuxd
     */
    public final ConnectType connectType;

    /**
     * 设备在usbmuxd上的位置id<br>
     * 基础信息，来自usbmuxd
     */
    public final int locationId;

    /**
     * 产品id<br>
     * 基础信息，来自usbmuxd
     */
    public final int productId;

    /**
     * 设备序列号，又称udid<br>
     * 基础信息，来自usbmuxd
     */
    public String serialNumber;

    /**
     * 解码必须得到的键
     */
    private static final String[] DECODE_KEYS = new String[]{"ConnectionType", "DeviceID", "SerialNumber"};

    /**
     * 根据连接状态解析详情数据<br>
     * 连接状态为断开时，只解析DeviceID
     *
     * @param nsDictionary  待解析的详情数据
     * @param connectStatus 连接状态
     */
    public DeviceConnectionDetail(NSDictionary nsDictionary, ConnectStatus connectStatus) {
        this.connectStatus = connectStatus;

        if (connectStatus == ConnectStatus.ATTACHED) {
//            log.debug(nsDictionary.toASCIIPropertyList());
            for (String key : DECODE_KEYS) {
                if (!nsDictionary.containsKey(key)) {
                    String errorText = "解析苹果设备连接详情时发生错误，期望读取到键" + key + "，但数据中不存在。";
                    logger.error(errorText);
                    throw new IllegalArgumentException(errorText);
                }
            }
        }

        if (nsDictionary.containsKey("ConnectionSpeed") && connectStatus == ConnectStatus.ATTACHED) {
            if (!(nsDictionary.get("ConnectionSpeed") instanceof NSNumber)) {
                String errorText = "解析苹果设备连接详情时发生错误，键ConnectionSpeed对应类型不为NSNumber";
                logger.error(errorText);
                throw new IllegalArgumentException(errorText);
            }
            NSNumber connectionSpeedNumber = (NSNumber) nsDictionary.get("ConnectionSpeed");
            connectionSpeed = connectionSpeedNumber.longValue();
        } else {
            connectionSpeed = 0L;
        }


        if (connectStatus == ConnectStatus.ATTACHED) {
            if (!(nsDictionary.get("ConnectionType") instanceof NSString)) {
                String errorText = "解析苹果设备连接详情时发生错误，键ConnectionType对应类型不为NSString";
                logger.error(errorText);
                throw new IllegalArgumentException(errorText);
            }
            NSString connectionTypeString = (NSString) nsDictionary.get("ConnectionType");
            connectType = ConnectType.fromString(connectionTypeString.getContent());
        } else {
            connectType = null;
        }

        if (!(nsDictionary.get("DeviceID") instanceof NSNumber)) {
            String errorText = "解析苹果设备连接详情时发生错误，键DeviceID对应类型不为NSNumber";
            logger.error(errorText);
            throw new IllegalArgumentException(errorText);
        }
        NSNumber deviceIdNumber = (NSNumber) nsDictionary.get("DeviceID");
        deviceId = deviceIdNumber.intValue();

        if (nsDictionary.containsKey("LocationID") && connectStatus == ConnectStatus.ATTACHED) {
            if (!(nsDictionary.get("LocationID") instanceof NSNumber)) {
                String errorText = "解析苹果设备连接详情时发生错误，键LocationID对应类型不为NSNumber";
                logger.error(errorText);
                throw new IllegalArgumentException(errorText);
            }
            NSNumber locationIdNumber = (NSNumber) nsDictionary.get("LocationID");
            locationId = locationIdNumber.intValue();
        } else {
            locationId = 0;
        }

        if (nsDictionary.containsKey("ProductID") && connectStatus == ConnectStatus.ATTACHED) {
            if (!(nsDictionary.get("ProductID") instanceof NSNumber)) {
                String errorText = "解析苹果设备连接详情时发生错误，键ProductID对应类型不为NSNumber";
                logger.error(errorText);
                throw new IllegalArgumentException(errorText);
            }
            NSNumber productIdNumber = (NSNumber) nsDictionary.get("ProductID");
            productId = productIdNumber.intValue();
        } else {
            productId = 0;
        }

        if (connectStatus == ConnectStatus.ATTACHED) {
            if (!(nsDictionary.get("SerialNumber") instanceof NSString)) {
                String errorText = "解析苹果设备连接详情时发生错误，键SerialNumber对应类型不为NSString";
                logger.error(errorText);
                throw new IllegalArgumentException(errorText);
            }
            NSString serialNumberString = (NSString) nsDictionary.get("SerialNumber");
            serialNumber = serialNumberString.getContent();
        } else {
            serialNumber = null;
        }

    }

    public DeviceConnectionDetail(int deviceId, long connectionSpeed, ConnectStatus connectStatus, ConnectType connectType, int locationId, int productId, String serialNumber) {
        this.deviceId = deviceId;
        this.connectionSpeed = connectionSpeed;
        this.connectStatus = connectStatus;
        this.connectType = connectType;
        this.locationId = locationId;
        this.productId = productId;
        this.serialNumber = serialNumber;
    }

    @Override
    public String toString() {
        return "DeviceConnectionDetail{" +
                "deviceId=" + deviceId +
                ", connectionSpeed=" + connectionSpeed +
                ", connectStatus=" + connectStatus +
                ", connectType=" + connectType +
                ", locationId=" + locationId +
                ", productId=" + productId +
                ", serialNumber='" + serialNumber + '\'' +
                '}';
    }

    /**
     * 连接状态
     */
    public enum ConnectStatus {
        /**
         * 有效连接中
         */
        ATTACHED,

        /**
         * 连接已断开
         */
        DETACHED
    }

    /**
     * 设备连接usbmuxd的方式
     */
    public enum ConnectType {
        /**
         * 通过USB线缆连接
         */
        USB,

        /**
         * 通过网络连接
         */
        NETWORK,

        /**
         * 其它，未知的新方式
         */
        OTHER;

        /**
         * 将字符串转换为枚举类型
         *
         * @param text 要转化的字符串
         * @return 对应的枚举类型
         */
        public static ConnectType fromString(String text) {
            ConnectType result = null;
            switch (text) {
                case "USB" :
                    result = USB;
                    break;
                case "NETWORK" :
                    result = NETWORK;
                    break;
                default :
                    result = OTHER;
                    break;
            };
            return result;
        }
    }
}
