using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace Tiku.Infrastructure.Security;

public sealed class DataProtectionKeyRingOptions
{
    public const string SectionName = "Security:DataProtection";

    public string ApplicationName { get; set; } = "Tiku.Api";
    public string CertificatePath { get; set; } = string.Empty;
    public string CertificatePassword { get; set; } = string.Empty;

    public static bool BeValid(DataProtectionKeyRingOptions options, bool requireCertificate)
    {
        return !string.IsNullOrWhiteSpace(options.ApplicationName) &&
               (!requireCertificate || !string.IsNullOrWhiteSpace(options.CertificatePath));
    }

    public X509Certificate2? LoadCertificate(bool requireCertificate)
    {
        if (string.IsNullOrWhiteSpace(CertificatePath))
        {
            if (requireCertificate)
            {
                throw new InvalidOperationException(
                    "Data Protection certificate is required outside Development. " +
                    "Configure Security:DataProtection:CertificatePath or " +
                    "TIKU_DATA_PROTECTION_CERTIFICATE_PATH.");
            }

            return null;
        }

        try
        {
            var certificate = X509CertificateLoader.LoadPkcs12FromFile(
                Path.GetFullPath(CertificatePath.Trim()),
                CertificatePassword,
                X509KeyStorageFlags.DefaultKeySet);
            if (!certificate.HasPrivateKey)
            {
                certificate.Dispose();
                throw new InvalidOperationException(
                    "Data Protection certificate must contain a private key.");
            }

            return certificate;
        }
        catch (InvalidOperationException)
        {
            throw;
        }
        catch (Exception exception) when (
            exception is CryptographicException or IOException or UnauthorizedAccessException)
        {
            throw new InvalidOperationException(
                "Data Protection certificate could not be loaded from the configured PKCS#12 file.",
                exception);
        }
    }
}
