import unittest
from unittest.mock import MagicMock

from nose.tools import assert_almost_equal

from helix.calculators.wind_pressure_calculator import WindPressureCalculator
from helix.constants.exposure_category import ExposureCategory


class WindPressureCalculatorTest(unittest.TestCase):
    def setUp(self):
        self.values = MagicMock()
        self.values.wind_speed.return_value = 110
        self.values.exposure_category_transition_distance.return_value = 1000
        self.subject = WindPressureCalculator(self.values)

    def test_kz_with_exposure_BC_and_roof_height_less_than_15_feet(self):
        assert_almost_equal(self.subject.calculate_k_z(12, ExposureCategory.B_C, 1000), 0.686, 3)

    def test_kz_with_exposure_BC_and_roof_height_greater_than_15_feet(self):
        assert_almost_equal(self.subject.calculate_k_z(100, ExposureCategory.B_C, 1000), 1.023, 3)

    def test_kz_with_exposure_CB_and_roof_height_less_than_30_feet(self):
        assert_almost_equal(self.subject.calculate_k_z(25, ExposureCategory.C_B, 1000), 0.856, 3)

    def test_kz_with_exposure_CB_and_roof_height_greater_than_30_feet(self):
        assert_almost_equal(self.subject.calculate_k_z(100, ExposureCategory.C_B, 1000), 1.139, 3)

    def test_qz_with_exposure_B_and_roof_height_greater_than_30_feet(self):
        self.values.building_height.return_value = 35
        self.values.exposure_category.return_value = ExposureCategory.B

        assert_almost_equal(self.subject.q_z(self.subject.K_z()), 19.276, 2)

    def test_qz_with_exposure_B_and_roof_height_less_than_30_feet(self):
        self.values.building_height.return_value = 12
        self.values.exposure_category.return_value = ExposureCategory.B

        assert_almost_equal(self.subject.q_z(self.subject.K_z()), 18.430, 2)

    def test_qz_with_exposure_C_and_roof_height_greater_than_15_feet(self):
        self.values.building_height.return_value = 35
        self.values.exposure_category.return_value = ExposureCategory.C

        assert_almost_equal(self.subject.q_z(self.subject.K_z()), 26.715, 2)

    def test_qz_with_exposure_C_and_roof_height_less_than_15_feet(self):
        self.values.building_height.return_value = 12
        self.values.exposure_category.return_value = ExposureCategory.C

        assert_almost_equal(self.subject.q_z(self.subject.K_z()), 22.35078017, 2)

    def test_qz_with_exposure_D_and_roof_height_greater_than_15_feet(self):
        self.values.building_height.return_value = 35
        self.values.exposure_category.return_value = ExposureCategory.D

        assert_almost_equal(self.subject.q_z(self.subject.K_z()), 31.432, 2)

    def test_qz_with_exposure_D_and_roof_height_less_than_15_feet(self):
        self.values.building_height.return_value = 12
        self.values.exposure_category.return_value = ExposureCategory.D

        assert_almost_equal(self.subject.q_z(self.subject.K_z()), 27.126, 2)
