import unittest
from unittest.mock import MagicMock
from nose.tools import eq_

from helix.calculators.ballast_calculator import BallastCalculator
from helix.constants.module_type import ModuleType
from helix.constants.panel_type import PanelType
from helix.constants.system_type import SystemType


class BallastAndTrayCountTest(unittest.TestCase):
    def setUp(self):
        self.values = MagicMock()
        self.system_type = SystemType.singleTilt
        self.module_type = ModuleType.Cell128
        self.values.system_type.return_value = self.system_type
        self.values.module_system_constants.return_value = self.system_type.module_constants(self.module_type)

        self.subject = BallastCalculator(self.values)
        self.panel_type = PanelType.EastWest
        self.ballast_block_weight = 20
        self.anchor_count = 0

    def test_no_ballast(self):
        self.force_to_resist = 0
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 0)
        eq_(result.link_tray_count, 0)
        eq_(result.cross_tray_count, 0)
        eq_(result.system_weight, 65.87)
        eq_(result.needs_anchor, False)

    def test_ballast_no_trays(self):
        self.force_to_resist = 140
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 4)
        eq_(result.link_tray_count, 0)
        eq_(result.cross_tray_count, 0)
        eq_(result.system_weight, 65.87)
        eq_(result.needs_anchor, False)

    def test_ballast_and_link_trays(self):
        self.force_to_resist = 230
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 9)
        eq_(result.link_tray_count, 1)
        eq_(result.cross_tray_count, 0)
        eq_(result.system_weight, 67.73)
        eq_(result.needs_anchor, False)

    def test_ballast_and_oscillate_between_0_and_1_link_trays(self):
        self.force_to_resist = 210
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 8)
        eq_(result.link_tray_count, 1)
        eq_(result.cross_tray_count, 0)
        eq_(result.system_weight, 67.73)
        eq_(result.needs_anchor, False)

    def test_ballast_and_link_tray_and_cross_tray(self):
        self.force_to_resist = 390
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 16)
        eq_(result.link_tray_count, 1)
        eq_(result.cross_tray_count, 1)
        eq_(result.system_weight, 70.88)
        eq_(result.needs_anchor, False)

    def test_ballast_and_link_tray_and_oscillate_between_0_and_1_cross_trays(self):
        self.force_to_resist = 330
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 14)
        eq_(result.link_tray_count, 1)
        eq_(result.cross_tray_count, 0)
        eq_(result.system_weight, 67.73)
        eq_(result.needs_anchor, False)

    def test_ballast_and_link_tray_and_2_cross_trays(self):
        self.force_to_resist = 570
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 25)
        eq_(result.link_tray_count, 1)
        eq_(result.cross_tray_count, 2)
        eq_(result.system_weight, 74.03)
        eq_(result.needs_anchor, False)

    def test_ballast_and_link_tray_and_at_first_2_then_1_cross_trays(self):
        self.force_to_resist = 515
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 23)
        eq_(result.link_tray_count, 1)
        eq_(result.cross_tray_count, 2)
        eq_(result.system_weight, 74.03)
        eq_(result.needs_anchor, False)

    def test_ballast_and_all_trays_and_anchor(self):
        self.force_to_resist = 770
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 35)
        eq_(result.link_tray_count, 1)
        eq_(result.cross_tray_count, 2)
        eq_(result.system_weight, 74.03)
        eq_(result.needs_anchor, True)

    def test_ballast_and_all_trays_and_at_first_anchor_then_no_anchor(self):
        self.force_to_resist = 675
        result = self.subject.ballast_and_tray_count(self.force_to_resist, self.panel_type, self.ballast_block_weight, self.anchor_count)

        eq_(result.ballast_count, 31)
        eq_(result.link_tray_count, 1)
        eq_(result.cross_tray_count, 2)
        eq_(result.system_weight, 74.03)
        eq_(result.needs_anchor, True)
