using AyCode.Services.Nav;

namespace AyCode.Services.Tests.Nav;

/// <summary>
/// A NAV authentikációs hash-ek (passwordHash, requestSignature) ellenőrzése — köztük a
/// hivatalos EKÁER PDF teszt-vektorával (eKAERManagementService_2.2.pdf §2.2.3). A rossz
/// aláírást a NAV elutasítja, ezért ez a legkritikusabb pont.
/// </summary>
[TestClass]
public class NavAuthHelperTests
{
    // Hivatalos teszt-vektor: requestId + timestamp(UTC) + signingKey → SHA-512 (UPPER hex).
    private const string OfficialRequestId = "TSTKFT1222564";
    private const string OfficialSigningKey = "Elek65Titkos";
    // PDF: timestamp = 2015.01.15T13:25:45+01:00 → a hash UTC megfelelőjét használja: 2015-01-15 12:25:45
    private static readonly DateTime OfficialTimestampUtc = new(2015, 1, 15, 12, 25, 45, DateTimeKind.Utc);
    private const string OfficialSignature =
        "AF84DC456B82234E67550C80169E517FBDAB4403607293985DECB09F534D9F73FADAABEFEE932554FABBC49F6E8F74A5DD54EA359D6B7644D95CFF3530AFB889";

    [TestMethod]
    public void ComputeRequestSignature_MatchesOfficialPdfTestVector()
    {
        var signature = NavAuthHelper.ComputeRequestSignature(OfficialRequestId, OfficialTimestampUtc, OfficialSigningKey);
        Assert.AreEqual(OfficialSignature, signature);
    }

    [TestMethod]
    public void ComputeRequestSignature_UsesUtcEquivalentOfTimestamp()
    {
        // A header-timestamp lehet más időzónában (CET +01:00) — a hash mégis a UTC-megfelelőt használja,
        // így ugyanazt az aláírást adja, mint a UTC 12:25:45.
        var cetTimestamp = new DateTimeOffset(2015, 1, 15, 13, 25, 45, TimeSpan.FromHours(1)).UtcDateTime;
        var signature = NavAuthHelper.ComputeRequestSignature(OfficialRequestId, cetTimestamp, OfficialSigningKey);
        Assert.AreEqual(OfficialSignature, signature);
    }

    [TestMethod]
    public void ComputeRequestSignature_IsDeterministic()
    {
        var a = NavAuthHelper.ComputeRequestSignature("REQ1", OfficialTimestampUtc, "KEY1");
        var b = NavAuthHelper.ComputeRequestSignature("REQ1", OfficialTimestampUtc, "KEY1");
        Assert.AreEqual(a, b);
    }

    [TestMethod]
    public void ComputePasswordHash_MatchesKnownSha512Vector()
    {
        // SHA-512("password") nagybetűs hex
        var hash = NavAuthHelper.ComputePasswordHash("password");
        Assert.AreEqual(
            "B109F3BBBC244EB82441917ED06D618B9008DD09B3BEFD1B5E07394C706A8BB980B1D7785E5976EC049B46DF5F1326AF5A2EA6D103FD07C95385FFAB0CACBC86",
            hash);
    }

    [TestMethod]
    public void ComputePasswordHash_Is128CharUpperHex()
    {
        var hash = NavAuthHelper.ComputePasswordHash("anyPassword123");
        Assert.AreEqual(128, hash.Length);
        Assert.IsTrue(
            hash.All(c => c is >= '0' and <= '9' or >= 'A' and <= 'F'),
            "A hash kizárólag nagybetűs hex karaktereket tartalmazhat.");
    }
}
