using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;

namespace DeviceInfoToAliIotHubViaGateway
{
    internal class Device3Tuple
    {
        internal Device3Tuple(string productKey, string deviceName, string deviceSecret) : this(null, productKey, deviceName, deviceSecret)
        {
        }

        internal Device3Tuple(string productName, string productKey, string deviceName, string deviceSecret)
        {
            this.ProductName = productName;
            this.ProductKey = productKey;
            this.DeviceName = deviceName;
            this.DeviceSecret = deviceSecret;
        }

        public string ProductName { get; set; }

        public string ProductKey { get; set; }
        public string DeviceName { get; set; }
        public string DeviceSecret { get; set; }
    }

    /// <summary>
    /// https://help.aliyun.com/document_detail/89298.html
    /// </summary>
    public class DynamicDevice2TupleParam
    {
        /// <summary>
        /// 子设备的名称。
        /// </summary>
        public string deviceName { get; set; }

        /// <summary>
        /// 子设备的产品Key。
        /// </summary>
        public string productKey { get; set; }
    }

    /// <summary>
    /// https://help.aliyun.com/document_detail/89298.html
    /// </summary>
    internal class DynamicDeviceRegResponseParam
    {
        /// <summary>
        /// 设备的唯一标识ID。
        /// </summary>
        public string iotId { get; set; }
        /// <summary>
        /// 设备秘钥。
        /// </summary>
        public string deviceSecret { get; set; }
        public string productKey { get; set; }
        public string deviceName { get; set; }
    }



    internal class DynamicDeviceRegRequest
    {
        /// <summary>
        /// 消息ID号。需定义为String类型的数字,且设备维度唯一
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// 协议版本号,目前协议版本号为1.0。 
        /// </summary>
        public string version => "1.0";

        /// <summary>
        /// 设备动态注册的参数。
        /// </summary>
        [JsonPropertyName("params")]
        public List<DynamicDevice2TupleParam> Params { get; set; }

        /// <summary>
        /// 请求方法,取值thing.sub.register。 
        /// </summary>
        public string method => "thing.sub.register";
    }

    internal class DynamicDeviceRegResponse
    {
        /// <summary>
        /// 结果信息。
        /// 200         succeed
        /// 460        request parameter error        请求参数错误。
        /// 6402        topo relation cannot add by self        设备不能将自己添加为自己的子设备。
        /// 401        request auth error        签名校验失败。
        /// </summary>
        public int code { get; set; }
        public List<DynamicDeviceRegResponseParam> data { get; set; }
        public string id { get; set; }


        public string message { get; set; }

        public string method { get; set; }
        public string version { get; set; }
    }






    /// <summary>
    /// https://help.aliyun.com/document_detail/89298.html
    /// </summary>
    internal class DynamicDeviceTopoAddRequestParam
    {
        /// <summary>
        /// 子设备的名称。
        /// </summary>
        public string deviceName { get; set; }

        /// <summary>
        /// 子设备的产品Key。
        /// </summary>
        public string productKey { get; set; }

        /// <summary>
        /// 签名。
        /// 加签算法:
        /// 1. 将所有提交给服务器的参数(sign,signMethod除外)按照字母顺序排序,然后将参数和值依次拼接(无拼接符号)。 
        /// 2. 对加签内容,需通过signMethod指定的加签算法,使用设备的DeviceSecret值,进行签名计算。
        /// 签名计算示例:
        /// sign= hmac_md5(deviceSecret, clientId123deviceNametestproductKey123timestamp1524448722000)
        /// </summary>
        public string sign { get; set; }

        public string signmethod => "hmacSha1";

        /// <summary>
        /// like 1524448722000
        /// </summary>
        public string timestamp { get; set; }

        /// <summary>
        /// 设备本地标记,非必填。可以设置为具体的productKey&deviceName。
        /// </summary>
        public string clientId { get; set; }
    }

    /// <summary>
    /// 添加设备拓扑关系
    /// </summary>
    internal class DynamicDeviceTopoAddRequest
    {
        /// <summary>
        /// 消息ID号。需定义为String类型的数字,且设备维度唯一
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// 协议版本号,目前协议版本号为1.0。 
        /// </summary>
        public string version => "1.0";

        /// <summary>
        /// 设备动态注册的参数。
        /// </summary>
        [JsonPropertyName("params")]
        public List<DynamicDeviceTopoAddRequestParam> Params { get; set; }

        /// <summary>
        /// 请求方法,取值:thing.topo.add。 
        /// </summary>
        public string method => "thing.topo.add";
    }

    /// <summary>
    /// 添加设备拓扑关系
    /// </summary>
    internal class DynamicDeviceTopoAddResponse
    {
        /// <summary>
        /// 结果信息。
        /// 200        succeed
        /// 6402        topo relation cannot add by self        设备不能把自己添加为自己的子设备。
        /// 401        request auth error        签名校验失败。
        /// </summary>
        public int code { get; set; }
        public object data { get; set; }
        public string id { get; set; }
        public string message { get; set; }
        public string method { get; set; }
        public string version { get; set; }
    }





    /// <summary>
    /// 删除设备的拓扑关系
    /// </summary>
    internal class DynamicDeviceTopoDeleteRequest
    {
        /// <summary>
        /// 消息ID号。需定义为String类型的数字,且设备维度唯一
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// 协议版本号,目前协议版本号为1.0。 
        /// </summary>
        public string version => "1.0";

        /// <summary>
        /// 设备动态注册的参数。
        /// </summary>
        [JsonPropertyName("params")]
        public List<DynamicDevice2TupleParam> Params { get; set; }

        /// <summary>
        /// 请求方法,取值thing.topo.delete。 
        /// </summary>
        public string method => "thing.topo.delete";
    }

    /// <summary>
    /// 删除设备的拓扑关系
    /// </summary>
    internal class DynamicDeviceTopoDeleteResponse
    {
        public string id { get; set; }

        /// <summary>
        /// 结果信息。
        /// 200        succeed
        /// 460        request parameter error        请求参数错误。
        /// 6100        device not found        设备不存在。
        /// </summary>
        public int code { get; set; }
        public object data { get; set; }
    }






    /// <summary>
    /// 获取设备的拓扑关系
    /// </summary>
    internal class DynamicDeviceTopoGetRequest
    {
        /// <summary>
        /// 消息ID号。需定义为String类型的数字,且设备维度唯一
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// 协议版本号,目前协议版本号为1.0。 
        /// </summary>
        public string version => "1.0";

        /// <summary>
        /// 
        /// </summary>
        [JsonPropertyName("params")]
        public List<DynamicDevice2TupleParam> Params { get; }

        /// <summary>
        /// 请求方法,取值thing.topo.get。 
        /// </summary>
        public string method => "thing.topo.get";
    }

    /// <summary>
    /// 获取设备的拓扑关系
    /// </summary>
    internal class DynamicDeviceTopoGetResponse
    {
        public string id { get; set; }

        /// <summary>
        /// 结果信息。
        /// 200        succeed
        /// 460        request parameter error        请求参数错误。
        /// </summary>
        public int code { get; set; }
        public List<DynamicDevice2TupleParam> data { get; set; }
    }





    /// <summary>
    /// 发现设备列表上报
    /// 在一些场景下,网关可以发现新接入的子设备。发现后,需将新接入子设备的信息上报云端,
    ///     然后通过数据流转到第三方应用,选择将哪些子设备接入该网关。
    /// </summary>
    internal class DynamicDeviceListFoundGetRequest
    {
        /// <summary>
        /// 消息ID号。需定义为String类型的数字,且设备维度唯一
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// 协议版本号,目前协议版本号为1.0。 
        /// </summary>
        public string version => "1.0";

        /// <summary>
        /// 
        /// </summary>
        [JsonPropertyName("params")]
        public List<DynamicDevice2TupleParam> Params { get; set; }

        /// <summary>
        /// 请求方法,取值thing.list.found。 
        /// </summary>
        public string method => "thing.list.found";
    }

    /// <summary>
    /// 发现设备列表上报
    /// </summary>
    internal class DynamicDeviceListFoundResponse
    {
        public string id { get; set; }

        /// <summary>
        /// 结果信息。
        /// 200        succeed
        /// 460        request parameter error        请求参数错误。
        /// 6250        product not found        上报的子设备产品不存在。
        /// 6280        devicename not meet specs       上报的子设备的名称不符规范,设备名称支持英文字母、数字和特殊字符-_@.:,长度限制4 ~32。
        /// </summary>
        public int code { get; set; }
        public object data { get; set; }
    }









    /// <summary>
    /// 通知网关添加设备拓扑关系
    /// 通知网关设备对子设备发起添加拓扑关系,可以配合发现设备列表上报功能使用。
    /// 可以通过数据流转获取设备返回的结果,数据流转Topic为/{productKey}/{deviceName}/thing/downlink/reply/message。 
    /// </summary>
    internal class DynamicDeviceTopoNotifyRequest
    {
        /// <summary>
        /// 消息ID号。需定义为String类型的数字,且设备维度唯一
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// 协议版本号,目前协议版本号为1.0。 
        /// </summary>
        public string version => "1.0";

        /// <summary>
        /// 
        /// </summary>
        [JsonPropertyName("params")]
        public List<DynamicDevice2TupleParam> Params { get; }

        /// <summary>
        /// 请求方法,取值thing.topo.add.notify。 
        /// </summary>
        public string method => "thing.topo.add.notify";
    }

    /// <summary>
    /// 通知网关添加设备拓扑关系
    /// </summary>
    internal class DynamicDeviceTopoNotifyResponse
    {
        public string id { get; set; }

        /// <summary>
        /// 结果信息。
        /// 200        succeed
        /// </summary>
        public int code { get; set; }
        public object data { get; set; }
    }






    /// <summary>
    /// 子设备上线
    /// https://help.aliyun.com/document_detail/89300.html
    /// </summary>
    internal class DynamicDeviceOnlineRequestParam
    {
        /// <summary>
        /// 子设备的产品Key。
        /// </summary>
        public string productKey { get; set; }

        /// <summary>
        /// 子设备的名称。
        /// </summary>
        public string deviceName { get; set; }

        /// <summary>
        /// 设备本地标记,非必填。可以设置为具体的productKey&deviceName。
        /// </summary>
        public string clientId { get; set; }

        /// <summary>
        /// like 1524448722000
        /// </summary>
        public string timestamp { get; set; }

        public string signMethod => "hmacSha1";

        /// <summary>
        /// 签名。
        /// 加签算法:
        /// 1. 将所有提交给服务器的参数(sign,signMethod除外)按照字母顺序排序,然后将参数和值依次拼接(无拼接符号)。 
        /// 2. 对加签内容,需通过signMethod指定的加签算法,使用设备的DeviceSecret值,进行签名计算。
        /// 签名计算示例:
        /// sign= hmac_md5(deviceSecret, clientId123deviceNametestproductKey123timestamp1524448722000)
        /// </summary>
        public string sign { get; set; }

        public string cleanSession => "true";
    }

    /// <summary>
    /// 子设备上线
    /// </summary>
    internal class DynamicDeviceOnlineRequest
    {
        public string id { get; set; }
        [JsonPropertyName("params")]
        public DynamicDeviceOnlineRequestParam Params { get; set; }
    }

    /// <summary>
    /// 子设备上线
    /// </summary>
    internal class DynamicDeviceOnlineResponse
    {
        /// <summary>
        /// 结果信息。
        /// 200        succeed
        /// 460        request parameter error        请求参数错误。
        /// 429        rate limit, too many subDeviceOnline msg in one minute       单个设备认证过于频繁被限流。
        /// 428        too many subdevices under gateway        网关下同时在线子设备过多。
        /// 6401        topo relation not exist         网关和子设备没有拓扑关系。
        /// 6100        device not found            子设备不存在。
        /// 521        device deleted           子设备已被删除。
        /// 522        device forbidden         子设备已被禁用。
        /// 6287        invalid sign            子设备密码或者签名错误。
        /// </summary>
        public int code { get; set; }
        public DynamicDevice2TupleParam data { get; set; }
        public string id { get; set; }


        public string message { get; set; }


    }








    /// <summary>
    /// 子设备下线
    /// </summary>
    internal class DynamicDeviceOfflineRequest
    {
        public string id { get; set; }
        [JsonPropertyName("params")]
        public DynamicDevice2TupleParam Params { get; set; }
    }

    /// <summary>
    /// 子设备下线
    /// </summary>
    internal class DynamicDeviceOfflineResponse
    {
        public string id { get; set; }

        /// <summary>
        /// 结果信息。
        /// 200        succeed
        /// 460        request parameter error        请求参数错误。
        /// 520        device no session           子设备会话不存在。
        /// </summary>
        public int code { get; set; }
        public string message { get; set; }

        public DynamicDevice2TupleParam data { get; set; }
    }

    /// <summary>
    /// {
    ///"id": "123",
    ///"version": "1.0",
    ///"params": {
    ///  "temperature": "30.5"
    ///},
    ///"method": "thing.service.property.set"
    ///}
    /// </summary>
    public class Alink_PropertyChanging_FromLocal
    {
        public string id { get; set; }
        public string version => "1.0";
        [JsonPropertyName("params")]
        public object Params { get; set; }
        public string method => "thing.event.property.post";
    }

    /// <summary>
    ///{
    ///  "id": "123",
    ///  "version": "1.0",
    ///  "params": {
    ///    "value": {
    ///      "errorCode": "error"
    ///    },
    ///    "time": 1524448722000
    ///  },
    ///  "method": "thing.event.alarm.post"
    ///}
    /// </summary>
    public class Alink_EventFiring_FromLocal
    {
        private string _method;
        public Alink_EventFiring_FromLocal(string eventName)
        {
            this._method = $"thing.event.{eventName}.post";
            this.time = DateTime.Now.Ticks;
        }

        public string id { get; set; }
        public string version => "1.0";
        public object sys => new { ack = 0 };
        [JsonPropertyName("params")]
        public object Params { get; set; }

        public long time { get; set; }
        public string method => this._method;
    }

    public class Alink_ServiceCalled_FromRemote
    {
        private string _method;
        public Alink_ServiceCalled_FromRemote(string eventName)
        {
            this._method = $"thing.event.{eventName}.post";
            this.time = DateTime.Now.Ticks;
        }

        public string id { get; set; }
        public string version => "1.0";
        public object sys => new { ack = 0 };
        [JsonPropertyName("params")]
        public object Params { get; set; }

        public long time { get; set; }
        public string method => this._method;
    }

    public class Alink_ThingModel_LogicalNozzle
    {
        public int CurState { get; set; }
        public int PumpId { get; set; }
        public string ProductName { get; set; }
        public double Price { get; set; }
        public double LastSaleVol { get; set; }
        public double LastSaleAmt { get; set; }
        public double CurSaleVol { get; set; }
        public double CurSaleAmt { get; set; }
        public double TotalizerVol { get; set; }
        public int SiteLevelNozzleId { get; set; }
        public string LastSaleTime { get; set; }
        public int LogicalId { get; set; }
    }
}