using BibliotekaTuringa;
using System.Net.Http.Headers;

namespace TestyJednostkoweTuring
{
    [TestClass]
    public class TestTuring
    {
        //zapisy taśm bez błędów
        string zapisTaśmy1 = "ABCdEFGH"; 
        string zapisTaśmy2 = "aBCDEFGH";

        /*
        //błędne
        string zapisTaśmy3 = "ABCDEFGh";
        string zapisTaśmy4 = "ABCDEFGH";
        string zapisTaśmy5 = "AbCdEFGH";
        string zapisTaśmy6 = "";
        string zapisTaśmy7 = "a";
        */

        //stany maszyny

        //program poprawny
        string[] program1 = { "qABq", "qBRs", "sBCd" };

        //niepoprawne programy
        string[] program2 = { "qAAq", "qBRs", "sBCd" };
        string[] program3 = { "qABq", "qARs", "sBCd" };
        string[] program4 = { };
        string[] program5 = { "qAbq", "qARs", "sBCd" };
        string[] program6 = { "QABq", "qARs", "sBCd" };
        string[] program7 = { "QABCq", "qARs", "sBCd" };

        [TestMethod]
        public void TestParsujZapisTaśmy1()
        {
            var stanMaszyny = Turing.ParsujZapisTaśmy(zapisTaśmy1);

            CollectionAssert.AreEqual(stanMaszyny.taśma, "ABCEFGH".ToArray());
            //Assert.AreEqual(stanMaszyny.taśma.ToString(), "ABCEFGH");
            Assert.AreEqual(stanMaszyny.stanGłowicy, 'd');
            Assert.AreEqual(stanMaszyny.położenieGłowicy, 3);
        }

        [TestMethod]
        public void TestParsujZapisTaśmy2()
        {
            var stanMaszyny = Turing.ParsujZapisTaśmy(zapisTaśmy2);

            CollectionAssert.AreEqual(stanMaszyny.taśma, "BCDEFGH".ToArray());
            Assert.AreEqual(stanMaszyny.stanGłowicy, 'a');
            Assert.AreEqual(stanMaszyny.położenieGłowicy, 0);
        }

        [TestMethod]
        public void TestSprawdźProgramPoprawny()
        {
            Turing.SprawdźProgram(program1); //TODO: jak zrobić to mądrzej
        }

        [TestMethod]
        [ExpectedException(typeof(TuringException))]
        public void TestSprawdźProgramNiepoprawny2()
        {
            Turing.SprawdźProgram(program2);
        }

        [TestMethod]
        [ExpectedException(typeof(TuringException))]
        public void TestSprawdźProgramNiepoprawny3()
        {
            Turing.SprawdźProgram(program3);
        }

        [TestMethod]
        [ExpectedException(typeof(TuringException))]
        public void TestSprawdźProgramNiepoprawny4()
        {
            Turing.SprawdźProgram(program4);
        }

        [TestMethod]
        [ExpectedException(typeof(TuringException))]
        public void TestSprawdźProgramNiepoprawny5()
        {
            Turing.SprawdźProgram(program5);
        }

        [TestMethod]
        [ExpectedException(typeof(TuringException))]
        public void TestSprawdźProgramNiepoprawny6()
        {
            Turing.SprawdźProgram(program6);
        }

        [TestMethod]
        [ExpectedException(typeof(TuringException))]
        public void TestSprawdźProgramNiepoprawny7()
        {
            Turing.SprawdźProgram(program7);
        }

        [TestMethod]
        public void TestCzytajTaśmę()
        {
            File.WriteAllText("test_taśma.txt", zapisTaśmy1);
            string testTaśma = Turing.CzytajTaśmę("test_taśma.txt");
            Assert.AreEqual(zapisTaśmy1.Length, testTaśma.Length);
            for (int i = 0; i < program1.Length; i++)
            {
                Assert.AreEqual(zapisTaśmy1, testTaśma);
            }
        }

        [TestMethod]
        public void TestCzytajProgram()
        {
            File.WriteAllLines("test_program.txt", program1);
            string[] testProgram = Turing.CzytajProgram("test_program.txt");
            Assert.AreEqual(program1.Length, testProgram.Length);
            for(int i = 0; i < program1.Length; i++)
            {
                Assert.AreEqual(program1[i], testProgram[i]);
            }
        }

        [TestMethod]
        public void TestKonstruktora1()
        {
            string taśma = "ABCEFGH";
            char stanGłowicy = 'd';
            int położenieGłowicy = 3;
            string[] program = { "qABq", "qBRs", "sBCd" };

            Turing t = new Turing(taśma.ToArray(), stanGłowicy, położenieGłowicy, program);

            //Assert.AreEqual(taśma, new string(t.taśma));
            Assert.AreEqual(taśma, new(t.taśma));
            Assert.AreEqual(stanGłowicy, t.stanGłowicy);
            Assert.AreEqual(położenieGłowicy, t.położenieGłowicy);
            Assert.AreEqual(program, t.program);
        }

        [TestMethod]
        [ExpectedException(typeof(TuringException))]
        public void TestKonstruktora2()
        {
            Turing t = new Turing(null, '@', -1, null);
        }

        [TestMethod]
        public void TestZapisStanuMaszyny()
        {
            File.WriteAllText("test_taśma1.txt", zapisTaśmy1);
            File.WriteAllLines("test_program1.txt", program1);
            Turing t = Turing.Load("test_taśma1.txt", "test_program1.txt");
            t.ZapiszStanMaszyny("test_taśma2.txt");
            string testTaśmy = File.ReadAllText("test_taśma2.txt");
            Assert.AreEqual(zapisTaśmy1, testTaśmy);
        }
    }
}