using System;
using System.IO;

namespace StellaOps.Scanner.WebService.Options;

/// <summary>
/// Post-configuration helpers for <see cref="ScannerWebServiceOptions"/>.
/// </summary>
public static class ScannerWebServiceOptionsPostConfigure
{
    public static void Apply(ScannerWebServiceOptions options, string contentRootPath)
    {
        ArgumentNullException.ThrowIfNull(options);
        ArgumentNullException.ThrowIfNull(contentRootPath);

        options.Plugins ??= new ScannerWebServiceOptions.PluginOptions();
        if (string.IsNullOrWhiteSpace(options.Plugins.Directory))
        {
            options.Plugins.Directory = Path.Combine("plugins", "scanner");
        }

        options.Authority ??= new ScannerWebServiceOptions.AuthorityOptions();
        var authority = options.Authority;
        if (string.IsNullOrWhiteSpace(authority.ClientSecret)
            && !string.IsNullOrWhiteSpace(authority.ClientSecretFile))
        {
            authority.ClientSecret = ReadSecretFile(authority.ClientSecretFile!, contentRootPath);
        }

        options.ArtifactStore ??= new ScannerWebServiceOptions.ArtifactStoreOptions();
        var artifactStore = options.ArtifactStore;
        if (string.IsNullOrWhiteSpace(artifactStore.SecretKey)
            && !string.IsNullOrWhiteSpace(artifactStore.SecretKeyFile))
        {
            artifactStore.SecretKey = ReadSecretFile(artifactStore.SecretKeyFile!, contentRootPath);
        }

        options.Signing ??= new ScannerWebServiceOptions.SigningOptions();
        var signing = options.Signing;
        if (string.IsNullOrWhiteSpace(signing.KeyPem)
            && !string.IsNullOrWhiteSpace(signing.KeyPemFile))
        {
            signing.KeyPem = ReadAllText(signing.KeyPemFile!, contentRootPath);
        }

        if (string.IsNullOrWhiteSpace(signing.CertificatePem)
            && !string.IsNullOrWhiteSpace(signing.CertificatePemFile))
        {
            signing.CertificatePem = ReadAllText(signing.CertificatePemFile!, contentRootPath);
        }

        if (string.IsNullOrWhiteSpace(signing.CertificateChainPem)
            && !string.IsNullOrWhiteSpace(signing.CertificateChainPemFile))
        {
            signing.CertificateChainPem = ReadAllText(signing.CertificateChainPemFile!, contentRootPath);
        }
    }

    private static string ReadSecretFile(string path, string contentRootPath)
    {
        var resolvedPath = ResolvePath(path, contentRootPath);
        if (!File.Exists(resolvedPath))
        {
            throw new InvalidOperationException($"Secret file '{resolvedPath}' was not found.");
        }

        var secret = File.ReadAllText(resolvedPath).Trim();
        if (string.IsNullOrEmpty(secret))
        {
            throw new InvalidOperationException($"Secret file '{resolvedPath}' is empty.");
        }

        return secret;
    }

    private static string ReadAllText(string path, string contentRootPath)
    {
        var resolvedPath = ResolvePath(path, contentRootPath);
        if (!File.Exists(resolvedPath))
        {
            throw new InvalidOperationException($"File '{resolvedPath}' was not found.");
        }

        return File.ReadAllText(resolvedPath);
    }

    private static string ResolvePath(string path, string contentRootPath)
        => Path.IsPathRooted(path)
            ? path
            : Path.GetFullPath(Path.Combine(contentRootPath, path));
}
