using Common.Attributes;
using DeviceCommand.Base;
using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Windows.Shapes;
using static Common.Attributes.ATSCommandAttribute;
using static System.Formats.Asn1.AsnWriter;

namespace DeviceCommand.Device
{
    /// <summary>
    /// 示波器（型号：RTM3004）
    /// </summary>
    [ATSCommand]
    [DeviceCategory("示波器")]
    public class RTM3004 : Tcp
    {
        /// <summary>
        /// 信号量锁
        /// </summary>
        public SemaphoreSlim semaphoreSlimLock { get; set; } = new(1, 1);

        #region 枚举定义（严格遵循手册规范）
        /// <summary>
        /// 单个通道名称枚举
        /// </summary>
        public enum ChannelName_Single_Enum
        {
            /// <summary>
            /// 通道1
            /// </summary>
            CH1 = 1,
            /// <summary>
            /// 通道2
            /// </summary>
            CH2 = 2,
            /// <summary>
            /// 通道3
            /// </summary>
            CH3 = 3,
            /// <summary>
            /// 通道4
            /// </summary>
            CH4 = 4
        }

        /// <summary>
        /// 测量项枚举，RTM3004支持8个独立的测量项
        /// </summary>
        public enum Measurement_Enum
        {
            /// <summary>测量项1</summary>
            MEAS1 = 1,
            /// <summary>测量项2</summary>
            MEAS2 = 2,
            /// <summary>测量项3</summary>
            MEAS3 = 3,
            /// <summary>测量项4</summary>
            MEAS4 = 4,
            /// <summary>测量项5</summary>
            MEAS5 = 5,
            /// <summary>测量项6</summary>
            MEAS6 = 6,
            /// <summary>测量项7</summary>
            MEAS7 = 7,
            /// <summary>测量项8</summary>
            MEAS8 = 8
        }

        /// <summary>
        /// 通道耦合模式枚举
        /// </summary>
        public enum CouplingMode
        {
            /// <summary>直流限制耦合</summary>
            DCLimit,
            /// <summary>交流限制耦合</summary>
            ACLimit,
            /// <summary>接地耦合，用于参考电平</summary>
            GND,
            /// <summary>直流耦合</summary>
            DC
        }

        /// <summary>
        /// 采集状态（手册 ACQuire:STATE 支持值）
        /// </summary>
        public enum AcquisitionState
        {
            /// <summary>运行中，持续采集波形</summary>
            RUN,
            /// <summary>采集完成后停止采集</summary>
            STOPping,
            /// <summary>采集完成（设置：不可用）</summary>
            COMPlete,
            /// <summary>立即中断当前采集</summary>
            BREak
        }

        /// <summary>
        /// 带宽限制（手册 CH<x>:BANdwidth 支持值）
        /// </summary>
        public enum BandwidthLimit
        {
            /// <summary>使用全部带宽，无限制</summary>
            FULL,
            /// <summary>频率限制为20 MHz，高频信号被移除以降低噪声</summary>
            B20
        }

        /// <summary>
        /// 触发模式（手册 TRIGger:A:MODe 支持值）
        /// </summary>
        public enum TriggerMode
        {
            /// <summary>自动模式，无触发时自动扫描</summary>
            AUTO,
            /// <summary>正常模式，仅在触发时采集</summary>
            NORMal,
        }

        /// <summary>
        /// 触发斜率/边沿枚举
        /// </summary>
        public enum Slope_Enum
        {
            /// <summary>上升沿触发，检测电压正向变化</summary>
            POSitive,
            /// <summary>下降沿触发，检测电压负向变化</summary>
            NEGative,
            /// <summary>上升和下降沿都触发</summary>
            EITHer
        }

        /// <summary>
        /// 参考电平百分比模式枚举
        /// 用于设置上升/下降时间测量的上下参考电平
        /// </summary>
        public enum Relative_Mode
        {
            /// <summary>10%、50%和90%参考电平</summary>
            TEN,
            /// <summary>20%、50%和80%参考电平</summary>
            TWENty,
            /// <summary>5%、50%和95%参考电平</summary>
            FIVE,
            /// <summary>用户自定义参考电平，需配合REFLevel参数使用</summary>
            USER
        }
        #endregion

        #region 核心控制命令
        //罗德与施瓦茨RTM3000示波器没有专门的"切换本地/远程"SCPI命令,自动切换

        /// <summary>
        /// 指定电源应用程序的电流源
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_CurrentSource(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"POWer:SOURce:CURRent {channelName}\n", ct); // 手册 POWer 命令规范
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 指定电源应用程序的电压源
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_VoltageSource(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"POWer:SOURce:VOLTage {channelName}\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }



        /// <summary>
        /// 用于设置上升/下降时间测量的上下参考电平
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="relativemode">参考电平的百分比</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Stop_QuickMeasurement(Tcp client, Relative_Mode relativemode, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"REFLevel:RELative:MODE{relativemode}:AOFF\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 启动快速测量(AUTO/NORMal)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="measurement">测试项</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Start_QuickMeasurement(Tcp client, Measurement_Enum measurement, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"MEASurement{measurement}:AON\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 停止快速测量
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="measurement">测试项</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Stop_QuickMeasurement(Tcp client, Measurement_Enum measurement, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"MEASurement{measurement}:AOFF\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 启动自动测量(AUTO/NORMal)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="measurement">测试项</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Start_AutoMeasurement(Tcp client, Measurement_Enum measurement, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"MEASurement{measurement}:ON\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 停止自动测量
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="measurement">测试项</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Stop_AutoMeasurement(Tcp client, Measurement_Enum measurement, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"MEASurement{measurement}:OFF\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 指定测量的通道
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道</param>
        /// <param name="measurement">测试项</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_Measurement_Source(Tcp client, ChannelName_Single_Enum channelName, Measurement_Enum measurement, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"MEASurement{measurement}:SOURce CH{channelName}\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }



        /// <summary>
        /// 指定A触发的通道 (AUTO/NORMal)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ATrigger_SOURce(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"TRIGger:A:SOURce CH{channelName}\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 设置A触发的模式 (AUTO/NORMal)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="mode">触发模式</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ATrigger_Mode(Tcp client, TriggerMode mode, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                string modeStr = mode.ToString().ToUpper();
                await SendAsync(client, $"TRIGger:A:MODE {modeStr}\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 设置A触发的触发斜率(沿)(AUTO/NORMal)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="slope">触发斜率(沿)</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ATrigger_Slope(Tcp client, Slope_Enum slope, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                string modeStr = slope.ToString().ToUpper();
                await SendAsync(client, $"TRIGger:A:EDGE:SLOPe {slope}\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 设置A触发的阈值电压(取决于垂直标度)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道</param>
        /// <param name="level">阈值电压/param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ATrigger_Level(Tcp client, ChannelName_Single_Enum channelName, float level, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                string modeStr = level.ToString().ToUpper();
                await SendAsync(client, $"TRIGger:A:LEVel {channelName} {level}\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 设置指定通道的输入耦合模式
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="couplingMode">耦合模式</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ChannelCoupling(Tcp client, ChannelName_Single_Enum channelName, CouplingMode couplingMode, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                string modeStr = couplingMode.ToString().ToUpper();
                await SendAsync(client, $"CHANnel {channelName}:COUPling{couplingMode}\n", ct); // 直接使用通道枚举值（如 CHANnel 1:COUPLING AC）
            }
            finally
            {
                semaphoreSlimLock.Release();


            }
        }


        /// <summary>
        /// 设置指定通道的输入耦合为DCLimit
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ChannelCoupling_DCLimit(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await Set_ChannelCoupling(client, channelName, CouplingMode.DCLimit, ct);
        }
        /// <summary>
        /// 设置指定通道的输入耦合为ACLimit
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ChannelCoupling_ACLimit(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await Set_ChannelCoupling(client, channelName, CouplingMode.ACLimit, ct);
        }
        /// <summary>
        /// 设置指定通道的输入耦合为GND
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ChannelCoupling_GND(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await Set_ChannelCoupling(client, channelName, CouplingMode.GND, ct);
        }

        /// <summary>
        /// 设置指定通道的输入耦合为DC
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ChannelCoupling_DC(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await Set_ChannelCoupling(client, channelName, CouplingMode.DC, ct);
        }


        /// <summary>
        /// 设置指定通道的硬件带宽限制
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="bandwidth">带宽限制</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ChannelBandwidth(Tcp client, ChannelName_Single_Enum channelName, BandwidthLimit bandwidth, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                string bwStr = $"{(int)bandwidth}E6";
                await SendAsync(client, $"CHANnel{channelName}:BANDwidth{bwStr}\n", ct); // 如 CHANnel 1:BANDwidth FULL
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 启用指定通道
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Start_Channel(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"CHANnel:{channelName}:STATe ON\n", ct); // 手册标准通道启用命令
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 关闭指定通道
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Stop_Channel(Tcp client, ChannelName_Single_Enum channelName, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"CHANnel:{channelName}:STATe OFF\n", ct); // 手册标准通道启用命令
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }



        /// <summary>
        /// 设置指定通道的垂直标度 (Volts/Div)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="channelName">通道名称</param>
        /// <param name="scale">标度值（单位：V/div）</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_ChannelScale(Tcp client, ChannelName_Single_Enum channelName, float scale, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"CHANnel{channelName}:SCALe{scale}\n", ct); // 如 CH1:SCALE 1.0（单位 V/div）
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 设置所有通道及数学波形的水平比例尺(每格时间，秒/格)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="scale">时基标度（单位：s/div）</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_Timebase_Scale(Tcp client, double scale, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"TIMebase:SCALe {scale}\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 设置水平触发位置 (相对于屏幕中心的偏移，百分比)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="position">位置百分比</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_Timebase_Position(Tcp client, double position, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"TIMebase:POSition {position}\n", ct); // 位置单位为百分比
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 设置示波器的采集状态 (RUN/STOP)
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="state">采集状态</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Set_Acquisition_State(Tcp client, AcquisitionState state, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                string stateStr = state.ToString().ToUpper();
                await SendAsync(client, $"ACQuire:STATe {stateStr}\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// Trigger 启动采集（替代原电源ON，手册无OUTPUT命令）
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Start_Acquisition(Tcp client, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"ACQuire:STATe RUN\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 采集完停止采集
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Stopping_Acquisition(Tcp client, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"ACQuire:STATe STOPping\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }

        /// <summary>
        /// 设置采集不可用
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Complete_Acquisition(Tcp client, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"ACQuire:STATe COMPlete\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }
        /// <summary>
        /// 立即停止采集
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Break_Acquisition(Tcp client, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                await SendAsync(client, $"ACQuire:STATe BREak\n", ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 保存波形数据（保存全通道到CSV文件）
        /// </summary>
        /// <param name="client">设备</param>_当前时间.CSV
        /// <param name="channelName">指定通道（默认：D:/BDUWAVE）</param>
        /// <param name="filePath">保存路径（默认：D:/BDUWAVE）</param>
        /// <param name="fileName">保存波形文件名（默认：WAVE_当前时间.PNG)</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Save_Waveform(Tcp client, ChannelName_Single_Enum channelName, string filePath, string fileName, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                if (!Directory.Exists(filePath))
                {
                    filePath = $"D:/WAVE";
                    Directory.CreateDirectory(filePath);
                }
                if (string.IsNullOrEmpty(fileName))
                {

                    fileName = $"WAVE_{DateTime.Now.ToString()}";

                }

                await SendAsync(client, $"EXPort:WAVeform:SOURce{channelName}\n", ct); // 设置待导出的波形源
                await SendAsync(client, $"EXPort:WFMSave:DESTination{filePath}\n", ct); // 设置待导出的目录
                await SendAsync(client, "FORMAT CSV\n", ct); // 设置文件格式
                await SendAsync(client, $"EXPort:WAVeform:NAME\"{fileName}\"\n", ct); //设置文件名字
                await SendAsync(client, $"EXPort:WAVeform:SAVE\n", ct);// 执行保存操作
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 保存屏幕截图（指定格式为PNG）
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="filePath">保存路径（默认：D:/BDUSCREEN）</param>
        /// <param name="fileName">保存波形文件名（默认：SCREEN_当前时间.PNG)</param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task Save_Screen_Image(Tcp client, string filePath, string fileName, CancellationToken ct = default)
        {
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                if (!Directory.Exists(filePath))
                {
                    filePath = $"D:/WAVE";
                    Directory.CreateDirectory(filePath);
                }
                if (string.IsNullOrEmpty(fileName))
                {

                    fileName = $"WAVE_{DateTime.Now.ToString()}";

                }
                await SendAsync(client, $"EXPort:SCRSave:DESTination{filePath}\n", ct); // 设置待导出的目录
                await SendAsync(client, "FORMAT PNG\n", ct); // 设置文件格式
                await SendAsync(client, $"MMEMory:NAME\"{fileName}\"\n", ct); //设置文件名字
                await SendAsync(client, $"HCOPy:IMMediate\n", ct);// 执行保存操作
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }


        /// <summary>
        /// 发送自定义SCPI命令
        /// </summary>
        /// <param name="client">设备</param>
        /// <param name="command">SCPI命令字符串</param>
        /// <param name="ct"></param>
        /// <returns>命令执行结果</returns>
        public async Task<string> Send_CustomCommand(Tcp client, string command, CancellationToken ct = default)
        {
            if (string.IsNullOrEmpty(command))
                throw new ArgumentNullException(nameof(command));
            await semaphoreSlimLock.WaitAsync(ct);
            try
            {
                return await WriteRead(client, $"{command}\n", "\n", ct: ct);
            }
            finally
            {
                semaphoreSlimLock.Release();
            }
        }
        #endregion
    }
}
