﻿using System;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Ric.Core.Commands.Bootstrap.ConversationCommand;

namespace Ric.Core.Tests.Commands.Bootstrap.ConversationCommand
{
    [TestClass]
    public class PatternToRegexParserTests
    {
        [TestMethod]
        public void Parse_PlainText_NoError()
        {
            var text = @"test test";
            var expected = @"test(?:\b.*?\b)test";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);

            Assert.AreEqual(expected, regex);
        }

        [TestMethod]
        public void Parse_PlainTextWithEscaping_NoError()
        {
            var text = @"tes\\t";
            var expected = @"tes\\t";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);

            Assert.AreEqual(expected, regex);
        }

        [TestMethod]
        public void Parse_PlainTextWithSet_NoError()
        {
            var text = @"test {test1 w, test2}";
            var expected = @"test(?:\b.*?\b)(?:test1\ w|test2)";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);

            Assert.AreEqual(expected, regex);
        }

        [TestMethod]
        public void Parse_PlainTextWithSetAndEscaping_NoError()
        {
            var text = @"test {test1,    test\}2}";
            var expected = @"test(?:\b.*?\b)(?:test1|test}2)";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);

            Assert.AreEqual(expected, regex);
        }

        [TestMethod]
        public void Parse_PlainTextWithVariables_NoError()
        {
            var text = @"$var1 $var2 test $var3";
            var expected = @"(?:\s|^)(?<var1>.*)(?:\s|$)(?:\b.*?\b)(?:\s|^)(?<var2>.*)(?:\s|$)(?:\b.*?\b)test(?:\b.*?\b)(?:\s|^)(?<var3>.*)(?:\s|$)";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);

            Assert.AreEqual(expected, regex);
        }

        [TestMethod]
        public void Parse_PlainTextWithAllCases1_NoError()
        {
            var text = @"$var1 \$var2 (test) {$var3, text1\, text2\}}";
            var expected = @"(?:\s|^)(?<var1>.*)(?:\s|$)(?:\b.*?\b)\$var2(?:\b.*?\b)\(test\)(?:\b.*?\b)(?:\$var3|text1,\ text2})";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);

            Assert.AreEqual(expected, regex);
        }

        [TestMethod]
        public void Parse_PlainTextWithAllCases2_NoError()
        {
            var text = @"{} test \y";
            var expected = @"(?:)(?:\b.*?\b)test(?:\b.*?\b)y";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);

            Assert.AreEqual(expected, regex);
        }

        [TestMethod]
        public void Parse_PlainTextWithRegexSpecialSymbol_NoError()
        {
            var text = @"() test []";
            var expected = @"\(\)(?:\b.*?\b)test(?:\b.*?\b)\[]";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);

            Assert.AreEqual(expected, regex);
        }

        [TestMethod]
        [ExpectedException(typeof(Exception))]
        public void Parse_NoSymbolsForEscaping_Error()
        {
            var text = @"test \";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);
        }

        [TestMethod]
        [ExpectedException(typeof(Exception))]
        public void Parse_EmptyNameVariable_Error()
        {
            var text = @"test $ test";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);
        }

        [TestMethod]
        [ExpectedException(typeof(Exception))]
        public void Parse_NoSymbolsAfterOpeningSetSymbol_Error()
        {
            var text = @"test {";
            var parser = new PatternToRegexParser();

            var regex = parser.Parse(text);
        }
    }
}
