using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace 加密狗
{
    public class 加密狗驱动类
    {
        // 保留原有方法，但添加新方法
        public static int 写入加密狗(ushort Index, string 管理密码, string 校验密码)
        {
            // 保持不变
            var re = 加密狗API类.VikeyFind(out var 加密狗数量);
            if (re != 0) return -1;
            加密狗API类.VikeyAdminLogin(Index, 管理密码);
            SHA256 sHA256 = SHA256.Create();
            加密狗API类.VikeyGetHID(Index, out uint pid);
            byte[] HID = BitConverter.GetBytes(pid);
            var pswd = Encoding.UTF8.GetBytes(校验密码);
            byte[] 校验数组 = HID.Concat(pswd).ToArray();
            var 校验值 = sHA256.ComputeHash(校验数组);
            加密狗API类.VikeyWriteData(Index, 0, 32, 校验值);
            byte[] randomBytes = new byte[96];
            Random random = new Random();
            random.NextBytes(randomBytes);
            加密狗API类.VikeyWriteData(Index, 32, 96, randomBytes);
            return 0;
        }

        /// <summary>
        /// 新方法：仅检查加密狗时间，不验证密码和数据
        /// </summary>
        public static int 寻找加密狗仅检查时间()
        {
            var re = 加密狗API类.VikeyFind(out var 加密狗数量);
            if (re != 0 || 加密狗数量 == 0) return -1;

            // 直接返回第一个找到的加密狗
            return 0;
        }

        /// <summary>
        /// 原有方法：寻找加密狗并进行完整验证
        /// </summary>
        public static int 寻找加密狗(string 用户密码, string 校验密码)
        {
            var re = 加密狗API类.VikeyFind(out var 加密狗数量);
            if (re != 0) return -1;
            int 找到的加密狗 = -1;
            for (ushort i = 0; i < 加密狗数量; i++)
            {
                re = 加密狗API类.VikeyUserLogin(i, 用户密码);
                if (检查加密狗数据(i, 校验密码)) return i;
            }
            return 找到的加密狗;
        }

        public static bool 检查加密狗数据(ushort Index, string 校验密码)
        {
            // 保持不变
            SHA256 sHA256 = SHA256.Create();
            加密狗API类.VikeyGetHID(Index, out uint pid);
            byte[] HID = BitConverter.GetBytes(pid);
            var pswd = Encoding.UTF8.GetBytes(校验密码);

            byte[] 校验数组 = HID.Concat(pswd).ToArray();
            var 校验值 = sHA256.ComputeHash(校验数组);
            var buffer = new byte[32];
            加密狗API类.VikeyReadData(Index, 0, 32, buffer);

            return buffer.SequenceEqual(校验值);
        }

        public static TimeSpan 检查剩余时间(int 加密狗)
        {
            ushort 序号 = (ushort)加密狗;

            // 尝试直接获取时间，不进行登录验证
            // 如果API需要登录才能获取时间，可能需要先进行简单登录
            try
            {
                加密狗API类.VikeyGetTime(序号, out 加密狗API类.SVikeyTime 现在时间);
                加密狗API类.VikeyGetValidTime(序号, out 加密狗API类.SVikeyTime 到期时间);

                DateTime _到期时间 = new DateTime();
                DateTime _现在时间 = new DateTime();
                try
                {
                    _到期时间 = new DateTime(到期时间.cYear, 到期时间.cMonth, 到期时间.cDay,
                                          到期时间.cHour, 到期时间.cMinute, 到期时间.cSecond);
                    _现在时间 = new DateTime(现在时间.cYear, 现在时间.cMonth, 现在时间.cDay,
                                          现在时间.cHour, 现在时间.cMinute, 现在时间.cSecond);
                }
                catch (Exception)
                {
                    return new TimeSpan(59, 59, 59, 59, 59);
                }

                return _到期时间 - _现在时间;
            }
            catch
            {
                // 如果获取时间失败，返回零
                return TimeSpan.Zero;
            }
        }
    }
}