# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg
#
# This file is part of Timeline.
#
# Timeline is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Timeline is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Timeline.  If not, see <http://www.gnu.org/licenses/>.


from timelinelib.test.cases.unit import UnitTestCase
from timelinelib.test.utils import human_time_to_gregorian
from timelinelib.calendar.timetype import TimeType
from timelinelib.canvas.data.timeperiod import TimePeriod


class TestTimeType(TimeType):
    pass


class DescribeTimeType(UnitTestCase):

    def test_name_not_implemented(self):
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.name
        self.assertEqual('The function name is not defined in class TestTimeType.', str(ctx.exception))

    def test_date_time_class_not_implemented(self):
        expected_exception_text = 'The function DateTimeClass is not defined in class TestTimeType.'
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.DateTimeClass
        self.assertEqual(expected_exception_text, str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.months_in_year
        self.assertEqual(expected_exception_text, str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.time_string('tm')
        self.assertEqual(expected_exception_text, str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.parse_time('2020-11-06 00:00:00')
        self.assertEqual(expected_exception_text, str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.days_in_week('time')
        self.assertEqual(expected_exception_text, str(ctx.exception))

    def test_delta_class_not_implemented(self):
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.DeltaClass
        self.assertEqual('The function DeltaClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.get_min_zoom_delta()
        self.assertEqual('The function DeltaClass is not defined in class TestTimeType.', str(ctx.exception))

    def test_time_class_not_implemented(self):
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.TimeClass
        self.assertEqual('The function TimeClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.get_min_time()
        self.assertEqual('The function TimeClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.get_max_time()
        self.assertEqual('The function TimeClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.get_min_wx_time()
        self.assertEqual('The function TimeClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.get_max_wx_time()
        self.assertEqual('The function TimeClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.get_default_time_period()
        self.assertEqual('The function TimeClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.now()
        self.assertEqual('The function TimeClass is not defined in class TestTimeType.', str(ctx.exception))

    def test_get_navigation_functions_not_implemented(self):
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.get_navigation_functions()
        self.assertEqual('The function get_navigation_functions is not defined in class TestTimeType.', str(ctx.exception))

    def test_choose_strip_not_implemented(self):
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.choose_strip(None, None)
        self.assertEqual('The function choose_strip is not defined in class TestTimeType.', str(ctx.exception))

    def test_equality(self):
        self.assertTrue(self.tt == self.tt)
        self.assertTrue(self.tt == TestTimeType())

    def test_inequality(self):
        self.assertTrue(TestTimeType() != TimeType())
        self.assertTrue(self.tt != TimeType())

    def test_format_period(self):
        with self.assertRaises(NotImplementedError) as ctx:
            start = human_time_to_gregorian("1 Jan 2020 00:00")
            end = human_time_to_gregorian("5 Jan 2020 00:01")
            period = TimePeriod(start, end)
            self.tt.format_period(period)
        self.assertEqual('The function DateTimeClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            start = human_time_to_gregorian("1 Jan 2020 00:00")
            end = human_time_to_gregorian("1 Jan 2020 00:00")
            period = TimePeriod(start, end)
            self.tt.format_period(period)
        self.assertEqual('The function DateTimeClass is not defined in class TestTimeType.', str(ctx.exception))
        with self.assertRaises(NotImplementedError) as ctx:
            start = human_time_to_gregorian("1 Jan 2020 00:01")
            end = human_time_to_gregorian("1 Jan 2020 00:01")
            period = TimePeriod(start, end)
            self.tt.format_period(period)
        self.assertEqual('The function DateTimeClass is not defined in class TestTimeType.', str(ctx.exception))

    def test_supports_saved_now(self):
        self.assertFalse(self.tt.supports_saved_now())

    def test_set_saved_now(self):
        self.tt.set_saved_now('time')

    def test_is_special_day(self):
        self.assertFalse(self.tt.is_special_day('time'))

    def test_get_duplicate_functions(self):
        df = self.tt.get_duplicate_functions()
        self.assertEqual(4, len(df))
        self.assertEqual(_('Day'), df[0][0])
        self.assertEqual(_('Week'), df[1][0])
        self.assertEqual(_('Month'), df[2][0])
        self.assertEqual(_('Year'), df[3][0])
        self.assertEqual(self.tt.move_period_num_days, df[0][1])
        self.assertEqual(self.tt.move_period_num_weeks, df[1][1])
        self.assertEqual(self.tt.move_period_num_months, df[2][1])
        self.assertEqual(self.tt.move_period_num_years, df[3][1])

    def test_create_time_picker_not_implemented(self):
        with self.assertRaises(NotImplementedError) as ctx:
            result = self.tt.create_time_picker(None)
        self.assertEqual('The function create_time_picker is not defined in class TestTimeType.', str(ctx.exception))

    def test_get_duration_types(self):
        self.assertEqual([self.tt.DURATION_TYPE_HOURS,
            self.tt.DURATION_TYPE_WORKDAYS,
            self.tt.DURATION_TYPE_DAYS,
            self.tt.DURATION_TYPE_MINUTES,
            self.tt.DURATION_TYPE_SECONDS], self.tt.get_duration_types())

    def test_get_duration_divisor(self):
        self.assertEqual(1, self.tt.get_duration_divisor(self.tt.DURATION_TYPE_SECONDS, 1))
        self.assertEqual(60, self.tt.get_duration_divisor(self.tt.DURATION_TYPE_MINUTES, 1))
        self.assertEqual(3600, self.tt.get_duration_divisor(self.tt.DURATION_TYPE_HOURS, 1))
        self.assertEqual(86400, self.tt.get_duration_divisor(self.tt.DURATION_TYPE_DAYS, 1))
        self.assertEqual(3600 * 7, self.tt.get_duration_divisor(self.tt.DURATION_TYPE_WORKDAYS, 7))

    def setUp(self):
        self.tt = TestTimeType()
