using Common.Attributes;
using DeviceCommand.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Common.Attributes.ATSCommandAttribute;

namespace DeviceCommand.Device
{
    /// <summary>
    /// 直流电源——三通道可编程直流电源设备（型号：IT-N6322B）
    /// </summary>
    [ATSCommand]
    [DeviceCategory("三通道可编程直流电源")]
    public class IT_N6322B : Tcp
    {
        /// <summary>
        /// 信号量锁
        /// </summary>
        public SemaphoreSlim semaphoreSlimLock { get; set; } = new(1, 1);

        /// <summary>
        /// 通道枚举
        /// </summary>
        public enum ChannelList_Enum
        {
            /// <summary>
            /// 通道1
            /// </summary>
            CH1 = 1,
            /// <summary>
            /// 通道2
            /// </summary>
            CH2 = 2,
            /// <summary>
            /// 通道3
            /// </summary>
            CH3 = 3
        }


        /// <summary>
        /// 切换为远程模式 三通道可编程直流电源
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_RemoteMode(Tcp client, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"SYST:REM\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 切换为本地模式
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_LocalMode(Tcp client, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"SYST:LOC\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }



        /// <summary>
        /// 设置源指定通道过电压保护电平
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="voltage">输出频率</param>
        /// <param name="ct">支持中途取消发送指令</param>
        /// <returns></returns>
        public async Task Set_OutputITVoltage(Tcp client, ChannelList_Enum channel, float voltage, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"VOLT {voltage},(@{channel} )\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 设置源指定通道过电压保护电平
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="voltage">输出频率</param>
        /// <param name="ct">支持中途取消发送指令</param>
        /// <returns></returns>
        public async Task Set_MaxITVoltage(Tcp client, ChannelList_Enum channel, float voltage, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"VOLT:OVER:PROT {voltage},(@{channel})\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 设置源指定通道的输出电流
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="current">输出频率</param>
        /// <param name="ct">支持中途取消发送指令</param>
        /// <returns></returns>
        public async Task Set_OutputITCurrent(Tcp client, ChannelList_Enum channel, float current, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"CURR {current},(@{channel})\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 设置源指定通道输出过电流保护电平
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="current">电压</param>
        /// <param name="ct">支持中途取消发送指令</param>
        /// <returns></returns>
        public async Task Set_MaxITCurrent(Tcp client, ChannelList_Enum channel, float current, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"CURR:OVER:PROT {current},(@{channel})\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 设置源指定通道输出的电压和电流值
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="voltage">电压</param>
        /// <param name="current">电流</param>
        /// <param name="ct">支持中途取消发送指令</param>
        /// <returns></returns>
        public async Task Set_CurrentAndVoltage(Tcp client, ChannelList_Enum channel, float voltage, float current, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"APPL {voltage},{current},(@{channel})\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 返回指定通道电源输出的实际电压值
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="ct">取消令牌</param>
        /// <returns>返回值是：定通道电源输出的实际电压值 (Amps)</returns>
        public async Task<string> Query_ITVoltage(Tcp client, ChannelList_Enum channel, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                return await WriteRead(client, $"MEAS:VOLT?,(@{channel})\r\n", "\n", ct: ct);

            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }



        /// <summary>
        /// 返回指定通道电源输出的实际电流值
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="ct">取消令牌</param>
        /// <returns>返回值是：设置的电流值 (Amps)</returns>
        public async Task<string> Query_ITCurrent(Tcp client, ChannelList_Enum channel, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                return await WriteRead(client, $"MEAS:CURR?,(@{channel})\r\n", "\n", ct: ct); // 使用缩写
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 返回指定通道电源输出的实际功率值
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="ct">取消令牌</param>
        /// <returns>返回值是：指定通道电源输出的实际功率值 (Amps)</returns>
        public async Task<string> Query_ITPower(Tcp client, ChannelList_Enum channel, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                return await WriteRead(client, $"MEAS:POW?,(@{channel})\r\n", "\n", ct: ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }



        /// <summary>
        /// 设置源指定通道的开启
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="ct">支持中途取消发送指令</param>
        /// <returns></returns>
        public async Task Set_ITPower_ON(Tcp client, ChannelList_Enum channel, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                //1/0 或 ON/OFF都可以
                await SendAsync(client, $"OUTP ON,(@{channel})\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 设置源指定通道的关闭
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channel">通道</param>
        /// <param name="ct">支持中途取消发送指令</param>
        /// <returns></returns>
        public async Task Set_ITPower_OFF(Tcp client, ChannelList_Enum channel, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"OUTP OFF,(@{channel})\n", ct);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }
    }
}

