namespace HanaTui.Hana;

/// <summary>
/// Represents a single parsed entry from hdbuserstore list output.
/// </summary>
public sealed class HdbUserstoreKey
{
    public string Name { get; init; } = "";
    public string Environment { get; init; } = "";  // raw ENV value e.g. host:30015@NDB
    public string User { get; init; } = "";

    // Parsed from Environment
    public string Host { get; init; } = "";
    public string Port { get; init; } = "";
    public string Tenant { get; init; } = "";

    public override string ToString() => Name;

    /// <summary>
    /// Parse a list of keys from the raw stdout of "hdbuserstore list".
    /// </summary>
    public static List<HdbUserstoreKey> ParseFrom(string output)
    {
        var keys = new List<HdbUserstoreKey>();
        var lines = output.Split('\n', StringSplitOptions.None);

        string currentName = "";
        string currentEnv = "";
        string currentUser = "";

        foreach (var rawLine in lines)
        {
            var line = rawLine.TrimEnd();

            if (line.StartsWith("KEY ", StringComparison.Ordinal))
            {
                // Flush previous key
                if (!string.IsNullOrEmpty(currentName))
                    keys.Add(Build(currentName, currentEnv, currentUser));

                currentName = line[4..].Trim();
                currentEnv = "";
                currentUser = "";
            }
            else if (line.TrimStart().StartsWith("ENV :", StringComparison.Ordinal))
            {
                currentEnv = line.TrimStart()[5..].Trim();
            }
            else if (line.TrimStart().StartsWith("USER:", StringComparison.Ordinal))
            {
                currentUser = line.TrimStart()[5..].Trim();
            }
        }

        // Flush last key
        if (!string.IsNullOrEmpty(currentName))
            keys.Add(Build(currentName, currentEnv, currentUser));

        return keys;
    }

    private static HdbUserstoreKey Build(string name, string env, string user)
    {
        // ENV format: host:port@TENANT  or  host:port
        string host = "", port = "", tenant = "";

        var atIdx = env.IndexOf('@');
        var hostPort = atIdx >= 0 ? env[..atIdx] : env;
        if (atIdx >= 0)
            tenant = env[(atIdx + 1)..];

        var colonIdx = hostPort.IndexOf(':');
        if (colonIdx >= 0)
        {
            host = hostPort[..colonIdx];
            port = hostPort[(colonIdx + 1)..];
        }
        else
        {
            host = hostPort;
        }

        return new HdbUserstoreKey
        {
            Name = name,
            Environment = env,
            User = user,
            Host = host,
            Port = port,
            Tenant = tenant,
        };
    }
}
