import unittest
from nose.tools import eq_
from helix.Repositories.graph_repository import GraphRepository
from helix.constants.panel_type import PanelType
from helix.constants.system_type import SystemType
from helix.models.coordinate import Coordinate
from helix.models.panel import Panel
from helix.models.subarray import Subarray


class GraphRepositoryTest(unittest.TestCase):
    def test_calculate_row_count_single_column(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 0)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 2)),
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 3)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].row_count, 4)
        eq_(subarrays[0].row_counted_geometrically, True)

    def test_calculate_row_count_box(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 0)), Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(1, 0)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1)), Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(1, 1)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 2)), Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(1, 2)),
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 3)), Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(1, 3)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].row_count, 4)
        eq_(subarrays[0].row_counted_geometrically, True)

    def test_calculate_row_count_H_shape(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 0)),                                                                                  Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(2, 0)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 1)), Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1)),
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 2)),                                                                                  Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(2, 2)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].row_count, 5)
        eq_(subarrays[0].row_counted_geometrically, True)

    # Below test is for https://www.pivotaltracker.com/story/show/128683099, uncomment when it's started.
    # def test_calculate_row_count_doughnut(self):
    #     panels = [
    #         Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 0)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0)), Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(2, 0)),
    #         Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1)),                                                                                  Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1)),
    #         Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 2)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 2)), Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(2, 2)),
    #     ]
    #     subarrays = [
    #         Subarray(subarray_number=0, origin=Coordinate(0, 0))
    #     ]
    #     GraphRepository(panels, subarrays, SystemType.dualTilt)
    #     eq_(subarrays[0].row_count, 4)

    def test_calculate_row_column_count_doughnut_with_double_wall(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 0)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 0)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 0)), Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(4, 0)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1)), Panel(subarray=0, panel_type=PanelType.Middle,     coordinate=Coordinate(1, 1)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1)), Panel(subarray=0, panel_type=PanelType.Middle,     coordinate=Coordinate(3, 1)), Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(4, 1)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 2)), Panel(subarray=0, panel_type=PanelType.EastWest,   coordinate=Coordinate(1, 2)),                                                                                  Panel(subarray=0, panel_type=PanelType.EastWest,   coordinate=Coordinate(3, 2)), Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(4, 2)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 3)), Panel(subarray=0, panel_type=PanelType.Middle,     coordinate=Coordinate(1, 3)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 3)), Panel(subarray=0, panel_type=PanelType.Middle,     coordinate=Coordinate(3, 3)), Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(4, 3)),
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 4)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 4)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 4)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 4)), Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(4, 4)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].row_count, 6)
        eq_(subarrays[0].row_counted_geometrically, False)
        eq_(subarrays[0].column_count, 6)
        eq_(subarrays[0].column_counted_geometrically, False)

    def test_calculate_row_count_fallback(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 0)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 0)),
            Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].row_count, 2)
        eq_(subarrays[0].row_counted_geometrically, False)

    def test_calculate_column_count_single_row(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 0)), Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].column_count, 4)
        eq_(subarrays[0].column_counted_geometrically, True)

    def test_calculate_column_count_box(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 0)), Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(1, 0)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1)), Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(1, 1)),
            Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 2)), Panel(subarray=0, panel_type=PanelType.EastWest, coordinate=Coordinate(1, 2)),
            Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(0, 3)), Panel(subarray=0, panel_type=PanelType.Corner,   coordinate=Coordinate(1, 3)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].column_count, 2)
        eq_(subarrays[0].column_counted_geometrically, True)

    def test_calculate_column_count_I_shape(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0)), Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0)),
                                                                                         Panel(subarray=0, panel_type=PanelType.EastWest,   coordinate=Coordinate(1, 1)),
            Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(0, 2)), Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 2)), Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(2, 2)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].column_count, 5)
        eq_(subarrays[0].column_counted_geometrically, True)

    def test_calculate_column_count_fallback(self):
        panels = [
            Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0)),
            Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(0, 0)),
            Panel(subarray=0, panel_type=PanelType.NorthSouth, coordinate=Coordinate(0, 0)),
            Panel(subarray=0, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0)),
        ]
        subarrays = [
            Subarray(subarray_number=0, origin=Coordinate(0, 0))
        ]
        GraphRepository(panels, subarrays, SystemType.dualTilt)
        eq_(subarrays[0].column_count, 2)
        eq_(subarrays[0].column_counted_geometrically, False)
