using System.Security.Cryptography;
using System.Text;

namespace OFACScraper.Helpers;

/// <summary>
/// Deterministic UUID v5 generation per CGSH spec (Ben Lok, 9 Mar 2026).
/// Both pub_id and doc_id use namespace 6ba7b811-9dad-11d1-80b4-00c04fd430c8 with the URL as input.
/// </summary>
public static class DeterministicGuid
{
    private static readonly Guid NamespaceUrl = Guid.Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8");

    public static Guid FromUrl(string url) => CreateV5(NamespaceUrl, url);

    private static Guid CreateV5(Guid namespaceId, string name)
    {
        var namespaceBytes = namespaceId.ToByteArray();
        SwapByteOrder(namespaceBytes);

        var nameBytes = Encoding.UTF8.GetBytes(name);
        var combined = new byte[namespaceBytes.Length + nameBytes.Length];
        Buffer.BlockCopy(namespaceBytes, 0, combined, 0, namespaceBytes.Length);
        Buffer.BlockCopy(nameBytes, 0, combined, namespaceBytes.Length, nameBytes.Length);

        var hashBytes = SHA1.HashData(combined);
        var guidBytes = new byte[16];
        Array.Copy(hashBytes, guidBytes, 16);

        guidBytes[6] = (byte)((guidBytes[6] & 0x0F) | 0x50);
        guidBytes[8] = (byte)((guidBytes[8] & 0x3F) | 0x80);

        SwapByteOrder(guidBytes);
        return new Guid(guidBytes);
    }

    private static void SwapByteOrder(byte[] guid)
    {
        (guid[3], guid[0]) = (guid[0], guid[3]);
        (guid[2], guid[1]) = (guid[1], guid[2]);
        (guid[5], guid[4]) = (guid[4], guid[5]);
        (guid[7], guid[6]) = (guid[6], guid[7]);
    }
}
