using System;
using System.IO;
using NUnit.Framework;

namespace Streamingle.Editor.Tests
{
    public sealed class AICameraCliRunnerTests
    {
        [Test]
        public void ResolveExecutablePrefersConfiguredWorker()
        {
            var root = CreateTemporaryDirectory();
            try
            {
                var configured = Path.Combine(root, "custom-worker.exe");
                File.WriteAllText(configured, string.Empty);

                Assert.That(
                    AICameraCliRunner.ResolveExecutable(
                        configured,
                        string.Empty,
                        string.Empty,
                        string.Empty),
                    Is.EqualTo(Path.GetFullPath(configured)));
            }
            finally
            {
                Directory.Delete(root, true);
            }
        }

        [Test]
        public void ResolveExecutableFindsConventionalDistributionFolder()
        {
            var root = CreateTemporaryDirectory();
            try
            {
                var worker = Path.Combine(
                    root,
                    "dist",
                    "CWCameraWorker",
                    AICameraCliRunner.ExecutableName);
                Directory.CreateDirectory(Path.GetDirectoryName(worker));
                File.WriteAllText(worker, string.Empty);

                Assert.That(
                    AICameraCliRunner.ResolveExecutable(
                        string.Empty,
                        root,
                        string.Empty,
                        string.Empty),
                    Is.EqualTo(Path.GetFullPath(worker)));
            }
            finally
            {
                Directory.Delete(root, true);
            }
        }

        [TestCase("plain", "plain")]
        [TestCase("two words", "\"two words\"")]
        [TestCase("", "\"\"")]
        public void QuoteArgumentUsesWindowsProcessEscaping(
            string argument,
            string expected)
        {
            Assert.That(AICameraCliRunner.QuoteArgument(argument), Is.EqualTo(expected));
        }

        [Test]
        public void JsonLineEventParsesProgressAndIdentity()
        {
            var parsed = AICameraCliRunner.TryParseEvent(
                "{\"type\":\"progress\",\"protocolVersion\":\"1\"," +
                "\"jobId\":\"unity-1\",\"phase\":\"generate\"," +
                "\"progress\":0.25,\"etaSeconds\":12.5}",
                out var cliEvent);

            Assert.That(parsed, Is.True);
            Assert.That(cliEvent.EventType, Is.EqualTo("progress"));
            Assert.That(cliEvent.JobId, Is.EqualTo("unity-1"));
            Assert.That(cliEvent.Progress, Is.EqualTo(0.25f));
            Assert.That(cliEvent.EtaSeconds, Is.EqualTo(12.5d));
        }

        [Test]
        public void PrefixedEventParsesButOrdinaryLogDoesNot()
        {
            Assert.That(
                AICameraCliRunner.TryParseEvent(
                    "CWAI_EVENT {\"eventType\":\"stage\",\"phase\":\"prepare\"}",
                    out var cliEvent),
                Is.True);
            Assert.That(cliEvent.EventType, Is.EqualTo("stage"));
            Assert.That(
                AICameraCliRunner.TryParseEvent("preparing camera data", out _),
                Is.False);
        }

        [Test]
        public void ResultEventParsesGeneratedOutputPath()
        {
            var expected = Path.Combine(
                Path.GetTempPath(),
                "cw-ai generated result");
            var jsonPath = expected.Replace("\\", "\\\\");

            Assert.That(
                AICameraCliRunner.TryParseEvent(
                    "{\"type\":\"result\",\"protocolVersion\":\"1\"," +
                    "\"outputPath\":\"" + jsonPath + "\"}",
                    out var cliEvent),
                Is.True);
            Assert.That(cliEvent.OutputPath, Is.EqualTo(expected));
        }

        private static string CreateTemporaryDirectory()
        {
            var path = Path.Combine(
                Path.GetTempPath(),
                "cw-ai-cli-runner-tests-" + Guid.NewGuid().ToString("N"));
            Directory.CreateDirectory(path);
            return path;
        }
    }
}
