using NUnit.Framework;
using NcProgramManager.Cnc.Fanuc;

namespace NcProgramManager.Tests.Unit
{
    [TestFixture]
    public class IsoProgramFormatterTests
    {
        // EnsureTitleBrackets
        // The formatter works on programs with a leading blank line then a title line.
        // e.g. "%\nO1234(COMMENT)\nG0...\n"
        // SplitFirstNonEmptyLine splits after the SECOND newline, so we need at least 2 newlines.

        private const string ProgramWithBrackets =
            "%\n<O1234>(COMMENT)\nG0 X0\nM30\n";

        private const string ProgramNoBrackets =
            "%\nO1234(COMMENT)\nG0 X0\nM30\n";

        private const string ProgramNoComment =
            "%\nO1234\nG0 X0\nM30\n";

        [Test]
        public void EnsureTitleBrackets_NoBrackets_AddsBrackets()
        {
            string result = IsoProgramFormatter.EnsureTitleBrackets(ProgramNoBrackets);

            Assert.That(result, Does.Contain("<O1234>"));
        }

        [Test]
        public void EnsureTitleBrackets_AlreadyHasBrackets_NoChange()
        {
            string result = IsoProgramFormatter.EnsureTitleBrackets(ProgramWithBrackets);

            Assert.That(result, Is.EqualTo(ProgramWithBrackets));
        }

        [Test]
        public void EnsureTitleBrackets_NullOrEmpty_ReturnsInput()
        {
            Assert.That(IsoProgramFormatter.EnsureTitleBrackets(null), Is.Null);
            Assert.That(IsoProgramFormatter.EnsureTitleBrackets(""), Is.EqualTo(""));
        }

        // InsertOrReplaceComment

        [Test]
        public void InsertOrReplaceComment_NoComment_InsertsComment()
        {
            string result = IsoProgramFormatter.InsertOrReplaceComment(ProgramNoComment, "TEST");

            Assert.That(result, Does.Contain("(TEST)"));
        }

        [Test]
        public void InsertOrReplaceComment_ExistingComment_ReplacesComment()
        {
            string result = IsoProgramFormatter.InsertOrReplaceComment(ProgramNoBrackets, "NEW");

            Assert.That(result, Does.Contain("(NEW)"));
            Assert.That(result, Does.Not.Contain("(COMMENT)"));
        }

        [Test]
        public void InsertOrReplaceComment_EmptyComment_InsertsEmptyParens()
        {
            string result = IsoProgramFormatter.InsertOrReplaceComment(ProgramNoComment, "");

            Assert.That(result, Does.Contain("()"));
        }

        [Test]
        public void InsertOrReplaceComment_NullOrEmpty_ReturnsInput()
        {
            Assert.That(IsoProgramFormatter.InsertOrReplaceComment(null, "X"), Is.Null);
            Assert.That(IsoProgramFormatter.InsertOrReplaceComment("", "X"), Is.EqualTo(""));
        }

        // RenameAndComment

        [Test]
        public void RenameAndComment_ProducesCorrectHeader()
        {
            string result = IsoProgramFormatter.RenameAndComment(ProgramNoBrackets, "O9999", "DESC");

            Assert.That(result, Does.StartWith("%\n<O9999>(DESC)"));
        }

        [Test]
        public void RenameAndComment_BodyAppendedAfterHeader()
        {
            string result = IsoProgramFormatter.RenameAndComment(ProgramNoBrackets, "O9999", "DESC");

            Assert.That(result, Does.Contain("G0 X0"));
        }

        [Test]
        public void RenameAndComment_NullOrEmpty_ReturnsInput()
        {
            Assert.That(IsoProgramFormatter.RenameAndComment(null, "X", "Y"), Is.Null);
            Assert.That(IsoProgramFormatter.RenameAndComment("", "X", "Y"), Is.EqualTo(""));
        }
    }
}
