using System;
using System.Security.Cryptography;
using System.Text;
using NUnit.Framework;
using NcProgramManager.Licensing;

namespace NcProgramManager.Tests.Unit
{
    [TestFixture]
    internal class LicenseValidatorTests
    {
        private RSACryptoServiceProvider _rsa;
        private string _publicKeyXml;
        private LicenseValidator _validator;

        [SetUp]
        public void SetUp()
        {
            _rsa = new RSACryptoServiceProvider(2048);
            _publicKeyXml = _rsa.ToXmlString(false);
            _validator = new LicenseValidator(_publicKeyXml);
        }

        [TearDown]
        public void TearDown()
        {
            _rsa.Dispose();
        }

        private string Sign(string fingerprint)
        {
            byte[] data = Encoding.UTF8.GetBytes(fingerprint);
            byte[] sig = _rsa.SignData(data, new SHA256CryptoServiceProvider());
            return Convert.ToBase64String(sig);
        }

        [Test]
        public void Validate_ValidLicense_ReturnsTrue()
        {
            string fingerprint = "CPU123BOARD456";
            string license = Sign(fingerprint);
            Assert.IsTrue(_validator.Validate(fingerprint, license));
        }

        [Test]
        public void Validate_WrongMachineFingerprint_ReturnsFalse()
        {
            string license = Sign("CPU123BOARD456");
            Assert.IsFalse(_validator.Validate("DIFFERENT_MACHINE", license));
        }

        [Test]
        public void Validate_TamperedLicense_ReturnsFalse()
        {
            string license = Sign("CPU123BOARD456");
            string tampered = license.Substring(0, license.Length - 4) + "AAAA";
            Assert.IsFalse(_validator.Validate("CPU123BOARD456", tampered));
        }

        [Test]
        public void Validate_EmptyLicense_ReturnsFalse()
        {
            Assert.IsFalse(_validator.Validate("CPU123BOARD456", string.Empty));
        }

        [Test]
        public void Validate_NotBase64_ReturnsFalse()
        {
            Assert.IsFalse(_validator.Validate("CPU123BOARD456", "not-base64!!!"));
        }

        [Test]
        public void LicenseFile_TryRead_NonExistentPath_ReturnsFalse()
        {
            bool result = LicenseFile.TryRead(@"C:\nonexistent\path\license.lic", out string base64);
            Assert.IsFalse(result);
            Assert.IsNull(base64);
        }

        [Test]
        public void Validate_EmptyFingerprint_ReturnsFalse()
        {
            // Empty fingerprint — matches no valid license; must not throw
            Assert.IsFalse(_validator.Validate(string.Empty, Sign("CPU123")));
        }
    }
}
