using ZB.MOM.WW.ScadaBridge.CLI.Commands;

namespace ZB.MOM.WW.ScadaBridge.CLI.Tests.Commands;

/// <summary>
/// Tests for <see cref="SecurityCommands"/> static helpers.
/// Fix 4 (review): the "Save this token now" advisory must reach stderr so that
/// piping stdout captures only the token (the actual secret), not the advisory text.
/// </summary>
[Collection("Console")]
public class SecurityCommandsTests
{
    /// <summary>
    /// The advisory line "Save this token now — it will not be shown again:" must be
    /// written to stderr, not stdout.
    /// </summary>
    [Fact]
    public void PrintCreatedKey_AdvisoryLine_WrittenToStderr_NotStdout()
    {
        var json = """{"keyId":"abc123","name":"Test","token":"sbk_abc123_secret"}""";

        var stdoutWriter = new StringWriter();
        var stderrWriter = new StringWriter();
        Console.SetOut(stdoutWriter);
        Console.SetError(stderrWriter);

        try
        {
            var exitCode = SecurityCommands.PrintCreatedKey(json);

            Assert.Equal(0, exitCode);

            var stdout = stdoutWriter.ToString();
            var stderr = stderrWriter.ToString();

            // The advisory must appear on stderr.
            Assert.Contains("Save this token now", stderr);
            Assert.Contains("will not be shown again", stderr);

            // The advisory must NOT appear on stdout (so pipe captures only the token).
            Assert.DoesNotContain("Save this token now", stdout);

            // The token itself must appear on stdout.
            Assert.Contains("sbk_abc123_secret", stdout);
        }
        finally
        {
            Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true });
            Console.SetError(new StreamWriter(Console.OpenStandardError()) { AutoFlush = true });
        }
    }

    /// <summary>
    /// The token value is written to stdout; piping <c>| xargs</c> captures only the token.
    /// The keyId info line also appears on stdout (it is not sensitive and does not impede piping
    /// since operators pipe the token line, not the whole output).
    /// </summary>
    [Fact]
    public void PrintCreatedKey_Token_WrittenToStdout()
    {
        var json = """{"keyId":"key-42","name":"MES","token":"sbk_key-42_mysecret"}""";

        var stdoutWriter = new StringWriter();
        var stderrWriter = new StringWriter();
        Console.SetOut(stdoutWriter);
        Console.SetError(stderrWriter);

        try
        {
            SecurityCommands.PrintCreatedKey(json);

            var stdout = stdoutWriter.ToString();

            Assert.Contains("sbk_key-42_mysecret", stdout);
            Assert.Contains("key-42", stdout);
        }
        finally
        {
            Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true });
            Console.SetError(new StreamWriter(Console.OpenStandardError()) { AutoFlush = true });
        }
    }
}
