using Levelcode_licenseCliente.Models;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

namespace Levelcode_licenseCliente.Security
{
    public static class LicenseEngine
    {
        // =========================
        // VALIDAR ARQUIVO .KEY
        // =========================
        public static LicensePayload ValidarArquivoKey(
            string caminhoArquivo,
            string chavePublicaXml)
        {
            if (!File.Exists(caminhoArquivo))
                throw new Exception("Arquivo de licença não encontrado.");

            string conteudo = File.ReadAllText(caminhoArquivo);

            string[] partes = conteudo.Split(new[] { "|SIGN|" },
                StringSplitOptions.None);

            if (partes.Length != 2)
                throw new Exception("Formato de licença inválido.");

            string payloadBase64 = partes[0];
            string assinaturaBase64 = partes[1];

            byte[] payloadBytes = Convert.FromBase64String(payloadBase64);
            byte[] assinaturaBytes = Convert.FromBase64String(assinaturaBase64);

            // 🔐 Verificar assinatura
            if (!VerificarAssinatura(payloadBytes, assinaturaBytes, chavePublicaXml))
                throw new Exception("Assinatura da licença inválida.");

            // 📦 Desserializar payload
            string json = Encoding.UTF8.GetString(payloadBytes);

            LicensePayload payload =
                JsonSerializer.Deserialize<LicensePayload>(json);

            if (payload == null)
                throw new Exception("Payload inválido.");

            return payload;
        }

        // =========================
        // VERIFICAR ASSINATURA RSA
        // =========================
        private static bool VerificarAssinatura(
            byte[] dados,
            byte[] assinatura,
            string chavePublicaXml)
        {
            using (RSA rsa = RSA.Create())
            {
                rsa.FromXmlString(chavePublicaXml);

                return rsa.VerifyData(
                    dados,
                    assinatura,
                    HashAlgorithmName.SHA256,
                    RSASignaturePadding.Pkcs1);
            }
        }
    }
}
