package com.thinkunion.park.service.common.iot.capability.device.discovery;

import com.google.gson.*;
import com.thinkunion.park.service.common.iot.capability.api.DeviceBasicData;
import com.thinkunion.park.service.common.iot.capability.device.payload.CommonResponsePayload;
import com.thinkunion.park.service.common.iot.capability.devicemodel.Profile;

import java.lang.reflect.Type;
import java.util.List;

public class DiscoveryResponsePayload extends CommonResponsePayload<DiscoveryResponsePayload.DiscoveryResponseData> {

    protected static final String TAG = "[Tmp]DiscoveryResponsePayload";

    public DiscoveryResponsePayload() {
    }

    public DeviceBasicData getDeviceInfo() {
        return this.data == null ? null : this.data.getDeviceBasicData();
    }

    public String getDeviceModel() {
        return this.data.getDeviceModel();
    }

    public static class DiscoveryResponseDataDeserializer implements
            JsonDeserializer<DiscoveryResponseData> {

        public DiscoveryResponseDataDeserializer() {
        }

        public DiscoveryResponseData deserialize(JsonElement json, Type typeOfT,
                                                 JsonDeserializationContext context) throws JsonParseException {
            DiscoveryResponseData responseData = null;
            if (json == null) {
                return responseData;
            } else if (!json.isJsonObject()) {
                return responseData;
            } else {
                responseData = new DiscoveryResponseData();
                JsonObject dataObject = json.getAsJsonObject();
                JsonElement deviceModelEle = dataObject.get("deviceModel");
                if (deviceModelEle != null && deviceModelEle.isJsonObject()) {
                    JsonObject deviceModelObj = deviceModelEle.getAsJsonObject();
                    JsonElement profileEle = deviceModelObj.get("info");
                    Profile profile = null;
                    if (profileEle != null) {
                        profile = (Profile) context.deserialize(profileEle, Profile.class);
                    }

                    if (profile != null) {
                        DeviceBasicData basicData = new DeviceBasicData();
                        basicData.setPk(profile.getProductKey());
                        basicData.setName(profile.getVersion());
                        basicData.setLocal(true);
                        responseData.setDeviceBasicData(basicData);
                    }

                    JsonElement propEle = deviceModelObj.get("props");
                    JsonElement serviceEle = deviceModelObj.get("services");
                    JsonElement eventEle = deviceModelObj.get("events");
                    if (propEle != null && propEle.isJsonArray() || serviceEle != null && serviceEle.isJsonArray()
                            || eventEle != null && eventEle.isJsonArray()) {
                        responseData.setDeviceModel(deviceModelEle.toString());
                    } else {
                        // TODO
                    }
                }

                JsonElement devices = dataObject.get("devices");
                if (devices != null) {
                    MulDevicesData mulDevicesData = (MulDevicesData) context
                            .deserialize(devices, MulDevicesData.class);
                    responseData.devices = mulDevicesData;
                }

                return responseData;
            }
        }
    }

    public static class MulDevicesData {

        public String addr;
        public int port;
        public List<Profile> profile;

        public MulDevicesData() {
        }
    }

    public static class DiscoveryResponseData {

        protected String deviceModel;
        protected DeviceBasicData deviceBasicData;
        public MulDevicesData devices;

        public DiscoveryResponseData() {
        }

        public String getDeviceModel() {
            return this.deviceModel;
        }

        public void setDeviceModel(String deviceModel) {
            this.deviceModel = deviceModel;
        }

        public DeviceBasicData getDeviceBasicData() {
            return this.deviceBasicData;
        }

        public void setDeviceBasicData(DeviceBasicData deviceBasicData) {
            this.deviceBasicData = deviceBasicData;
        }
    }
}
