﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Day18Test
{
    using Day18;

    using InputReader;

    using Shouldly;

    using Xunit;

    public class Class1
    {
        [Fact]
        public void TestParseExample()
        {
            string def = @".#.#.#
...##.
#....#
..#...
#.#..#
####..";
            var grid = def.CreateLightGrid(6, 6);

            grid[0, 0].ShouldBe(false);
            grid[0, 1].ShouldBe(true);
            grid[0, 2].ShouldBe(false);
            grid[0, 3].ShouldBe(true);
            grid[0, 4].ShouldBe(false);
            grid[0, 5].ShouldBe(true);

            grid[1, 0].ShouldBe(false);
            grid[1, 1].ShouldBe(false);
            grid[1, 2].ShouldBe(false);
            grid[1, 3].ShouldBe(true);
            grid[1, 4].ShouldBe(true);
            grid[1, 5].ShouldBe(false);

            grid[2, 0].ShouldBe(true);
            grid[2, 1].ShouldBe(false);
            grid[2, 2].ShouldBe(false);
            grid[2, 3].ShouldBe(false);
            grid[2, 4].ShouldBe(false);
            grid[2, 5].ShouldBe(true);

            grid[3, 0].ShouldBe(false);
            grid[3, 1].ShouldBe(false);
            grid[3, 2].ShouldBe(true);
            grid[3, 3].ShouldBe(false);
            grid[3, 4].ShouldBe(false);
            grid[3, 5].ShouldBe(false);

            grid[4, 0].ShouldBe(true);
            grid[4, 1].ShouldBe(false);
            grid[4, 2].ShouldBe(true);
            grid[4, 3].ShouldBe(false);
            grid[4, 4].ShouldBe(false);
            grid[4, 5].ShouldBe(true);

            grid[5, 0].ShouldBe(true);
            grid[5, 1].ShouldBe(true);
            grid[5, 2].ShouldBe(true);
            grid[5, 3].ShouldBe(true);
            grid[5, 4].ShouldBe(false);
            grid[5, 5].ShouldBe(false);
        }

        [Fact]
        public void TestToggleExample()
        {
            string start = @".#.#.#
...##.
#....#
..#...
#.#..#
####..";
            var grid = start.CreateLightGrid(6, 6);
            grid.CalcLit().ShouldBe(15);

            grid = grid.IterateLightGrid(LightCalculator.CalcLight);
            string result = grid.ToStringGrid();
            string end = @"..##..
..##.#
...##.
......
#.....
#.##..
";
            result.ShouldBe(end);
            grid.CalcLit().ShouldBe(11);

            grid = grid.IterateLightGrid(LightCalculator.CalcLight);
            result = grid.ToStringGrid();
            end = @"..###.
......
..###.
......
.#....
.#....
";
            result.ShouldBe(end);
            grid.CalcLit().ShouldBe(8);

            grid = grid.IterateLightGrid(LightCalculator.CalcLight);
            result = grid.ToStringGrid();
            end = @"...#..
......
...#..
..##..
......
......
";
            result.ShouldBe(end);
            grid.CalcLit().ShouldBe(4);

            grid = grid.IterateLightGrid(LightCalculator.CalcLight);
            result = grid.ToStringGrid();
            end = @"......
......
..##..
..##..
......
......
";
            result.ShouldBe(end);
            grid.CalcLit().ShouldBe(4);
        }

        private System.IO.Stream CreateResource()
        {
            return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Day18Test.input.txt");
        }


        [Fact]
        public void TestA()
        {
            using (var stream = CreateResource())
            {
                var grid = InputReader.ReadResource(stream).CreateLightGrid(100,100);
                for (int n = 0; n < 100; n++)
                {
                    grid = grid.IterateLightGrid(LightCalculator.CalcLight);
                }

                int lit = grid.CalcLit();
                lit.ShouldBe(768);
            }
        }

        [Fact]
        public void TestB()
        {
            using (var stream = CreateResource())
            {
                var grid = InputReader.ReadResource(stream).CreateLightGrid(100, 100);
                grid[0, 0] = true;
                grid[99, 0] = true;
                grid[0, 99] = true;
                grid[99, 99] = true;
                for (int n = 0; n < 100; n++)
                {
                    grid = grid.IterateLightGrid(
                        (grd, x, y) =>
                            {
                                if ((x == 0 || x == 99) && (y == 0 || y == 99))
                                {
                                    return true;
                                }

                                return LightCalculator.CalcLight(grd, x, y);
                            }
                        );
                }

                int lit = grid.CalcLit();
                lit.ShouldBe(781);
            }
        }
    }
}
