using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HighWayIot.Plc
{
    /// <summary>
    /// byte和ushort转换
    /// </summary>
    public static class EndianConvert
    {
        /// <summary>
        /// 将 ushort 转换为 byte[]（默认小端序）
        /// </summary>
        /// <param name="value">要转换的 ushort 值</param>
        /// <param name="isBigEndian">是否使用大端序（默认false）</param>
        public static byte[] ToBytes(this ushort value, bool isBigEndian = false)
        {
            byte[] bytes = BitConverter.GetBytes(value);

            // 系统是小端序且需要大端序时，反转字节数组
            if (BitConverter.IsLittleEndian && isBigEndian)
            {
                Array.Reverse(bytes);
            }
            // 系统是大端序且需要小端序时，反转字节数组
            else if (!BitConverter.IsLittleEndian && !isBigEndian)
            {
                Array.Reverse(bytes);
            }

            return bytes;
        }

        /// <summary>
        /// 将 byte[] 转换为 ushort（默认小端序）
        /// </summary>
        /// <param name="bytes">要转换的字节数组（长度必须 >= 2）</param>
        /// <param name="isBigEndian">是否使用大端序（默认false）</param>
        /// <exception cref="ArgumentException">输入数组长度不足</exception>
        public static ushort FromBytes(this byte[] bytes, bool isBigEndian = false)
        {
            if (bytes.Length < 2)
            {
                throw new ArgumentException("字节数组长度必须至少为2", nameof(bytes));
            }

            // 复制前两个字节以避免修改原始数组
            byte[] tempBytes = new byte[2];
            Array.Copy(bytes, tempBytes, 2);

            // 根据系统字节序和目标字节序决定是否反转
            bool systemIsBigEndian = !BitConverter.IsLittleEndian;
            if (isBigEndian != systemIsBigEndian)
            {
                Array.Reverse(tempBytes);
            }

            return BitConverter.ToUInt16(tempBytes, 0);
        }

        /// <summary>
        /// 安全版本：从指定偏移量开始转换（不抛异常）
        /// </summary>
        public static bool TryFromBytes(this byte[] bytes, out ushort result, int startIndex = 0, bool isBigEndian = false)
        {
            result = 0;
            if (bytes == null || bytes.Length < startIndex + 2)
            {
                return false;
            }

            byte[] tempBytes = new byte[2];
            Array.Copy(bytes, startIndex, tempBytes, 0, 2);

            bool systemIsBigEndian = !BitConverter.IsLittleEndian;
            if (isBigEndian != systemIsBigEndian)
            {
                Array.Reverse(tempBytes);
            }

            result = BitConverter.ToUInt16(tempBytes, 0);
            return true;
        }
    }
}
