# 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 unittest.mock import Mock

from timelinelib.canvas.drawing.viewproperties import ViewProperties
from timelinelib.canvas.data.memorydb.db import MemoryDB
from timelinelib.test.cases.unit import UnitTestCase
from timelinelib.test.utils import a_subevent_with, an_event_with, a_container_with
from timelinelib.wxgui.dialogs.setcontainer.controller import SetContainerDialogController
from timelinelib.wxgui.dialogs.setcontainer.view import SetContainerDialog


class describe_set_container_dialog_controller(UnitTestCase):

    def setUp(self):
        self.view = Mock(SetContainerDialog)
        self.controller = SetContainerDialogController(self.view)
        self.view_properties = Mock(ViewProperties)
        self.main_frame = Mock()
        self.main_frame.view_properties = self.view_properties
        self.db = MemoryDB()
        self.newcontainer = a_container_with('New Container')
        self.container = a_container_with('Container')
        self.event1 = an_event_with(time="1 Jan 2010", text='event-1')
        self.event2 = an_event_with(time="1 Jan 2010", text='event-2')
        self.subevent1 = a_subevent_with(time="1 Jan 2010", text='event-1', container=self.container)
        self.subevent2 = a_subevent_with(time="1 Jan 2010", text='event-2', container=self.container)
        self.db.save_event(self.container)
        self.db.save_event(self.event1)
        self.db.save_event(self.event2)
        self.db.save_event(self.subevent1)
        self.db.save_event(self.subevent2)
        self.view.GetSelectedContainer.return_value = self.newcontainer

    def test_container_can_be_set_on_all_events(self):
        # Setup
        self.assert_container_has_no_subevents()
        self.assert_original_events_is_in_db()
        # Given
        self.controller.on_init(self.main_frame, self.db, [self.event1.id, self.event2.id])
        # When
        self.controller.on_ok_clicked()
        # Then
        self.assert_container_has_subevents_cloned_from_original_events()
        self.assert_original_events_deleted_from_db()
        self.view.EndModalOk.assert_called_with()

    def test_selecting_no_container_and_clicking_ok_removes_events_from_container(self):
        self.controller.on_init(self.main_frame, self.db, [self.subevent1.id, self.subevent2.id])
        self.view.GetSelectedContainer.return_value = None
        self.assertEqual(2, len(self.db.find_event_with_id(self.container.id).subevents))
        self.controller.on_ok_clicked()
        self.assertEqual(0, len(self.db.find_event_with_id(self.container.id).subevents))

    def assert_container_has_no_subevents(self):
        self.assertEqual(0, len(self.newcontainer.subevents))

    def assert_original_events_is_in_db(self):
        self.assertTrue(self.db.find_event_with_id(self.event1.id) is not None)
        self.assertTrue(self.db.find_event_with_id(self.event2.id) is not None)

    def assert_container_has_subevents_cloned_from_original_events(self):
        self.assertEqual(2, len(self.newcontainer.subevents))
        self.assertEqual('event-1', self.newcontainer.subevents[0].text)
        self.assertEqual('event-2', self.newcontainer.subevents[1].text)

    def assert_original_events_deleted_from_db(self):
        self.assertTrue(self.db.find_event_with_id(self.event1.id) is None)
        self.assertTrue(self.db.find_event_with_id(self.event2.id) is None)
