"""Setup/installation tests for this package."""

from datetime import datetime
from DateTime import DateTime
from plone import api
from plone.app.contenttypes.interfaces import IEvent
from plone.app.testing.interfaces import SITE_OWNER_NAME
from plone.event.interfaces import IICalendarEventComponent
from plone.testing import zope as zope_testing
from ploneintranet import api as pi_api
from ploneintranet.calendar.browser.app import View as CalendarAppView
from ploneintranet.calendar.browser.tiles import FullCalendarTile
from ploneintranet.calendar.config import DEFAULT_TZ_ID
from ploneintranet.calendar.config import TZ_COOKIE_NAME
from ploneintranet.calendar.importexport import import_ics
from ploneintranet.calendar.testing import IntegrationTestCase
from ploneintranet.calendar.utils import get_pytz_timezone
from ploneintranet.calendar.utils import get_timezone_info
from ploneintranet.calendar.utils import pytz_zone
from ploneintranet.calendar.utils import tzid_from_dt
from pytz import timezone
from z3c.relationfield.relation import RelationValue
from zope.component import getUtility
from zope.intid.interfaces import IIntIds

PROJECTNAME = "ploneintranet.calendar"


class TestCalendarIntegration(IntegrationTestCase):
    def test_calendar_ics_import(self):
        with api.env.adopt_roles(["TeamManager"]):
            self.assertEqual(import_ics(self.workspace, TEST_ICS), 5)

    def test_get_timezone_data(self):
        view = FullCalendarTile(self.portal.apps.calendar, self.request)
        data = view.get_timezone_data()
        # assuming we should have many, but they can grow over time
        self.assertTrue(len(data) > 80)
        berlin = [x for x in data if x["zone"] == "Europe/Berlin"][0]
        self.assertTrue("Berlin" in berlin["name"])

    def test_timezone_cookie(self):
        view = FullCalendarTile(self.portal.apps.calendar, self.request)
        self.assertTrue(TZ_COOKIE_NAME not in self.request.RESPONSE.cookies)
        tz = view.get_user_timezone()
        self.assertTrue(tz == "UTC")  # default in vanilla quaive

        view.set_user_timezone("Asia/Kabul")

        self.assertTrue(TZ_COOKIE_NAME in self.request.RESPONSE.cookies)
        self.assertTrue(
            self.request.RESPONSE.cookies[TZ_COOKIE_NAME]["value"] == "Asia/Kabul"
        )

        # Fake roundtrip to set the cookie
        self.request.set(TZ_COOKIE_NAME, "US/East-Indiana")
        tz = view.get_user_timezone()
        self.assertTrue(tz == "US/East-Indiana")

    def test_id2class(self):
        view = CalendarAppView(self.portal.apps.calendar, self.request)
        self.assertTrue(view.id2class("my-w:o+rk.s(p)a&ce") == "cal-cat-my-work-space")

    #
    # fullcalendar tile
    #
    def test_get_start_date(self):
        tile = FullCalendarTile(self.portal.apps.calendar, self.request)
        self.assertTrue(tile.get_start_date() == datetime.now().strftime("%Y-%m-%d"))

        self.request.form["day"] = "31"
        self.request.form["month"] = "04"
        self.request.form["year"] = "1000"
        tile = FullCalendarTile(self.portal.apps.calendar, self.request)
        self.assertTrue(tile.get_start_date() == "1000-04-31")

    #
    # utils
    #
    def test_tzid_from_dt(self):
        self.assertTrue(tzid_from_dt(datetime.now()) == DEFAULT_TZ_ID)

        amsterdam = timezone("Europe/Amsterdam")
        now_in_ams = amsterdam.localize(datetime.now())

        self.assertTrue(tzid_from_dt(now_in_ams) == 31)

    def test_get_pytz_timezone(self):
        self.assertTrue(get_pytz_timezone(30).zone == "Europe/London")

    def test_get_timezone_info(self):
        # Just test that this works for every timezone and for every hour
        for tzid in sorted(pytz_zone):
            get_timezone_info(tzid)


class TestCalendarFunctional(IntegrationTestCase):
    def setUp(self):
        super().setUp()
        zope_testing.login(self.layer["app"]["acl_users"], SITE_OWNER_NAME)
        self.calendar = api.content.create(
            container=self.portal.calendars,
            title="My calendar",
            type="ploneintranet.calendar.central_calendar",
        )
        self.event = api.content.create(
            container=self.workspace,
            title="My event",
            id="my-event",
            start=DateTime(),
            end=DateTime() + 1,
            whole_day=True,
            type="Event",
        )
        intids = getUtility(IIntIds)
        cal_intid = intids.getId(self.calendar)
        self.event.shared_calendar = RelationValue(cal_intid)
        self.event.reindexObject()

    def test_set_shared_calendar(self):
        brains = api.content.find(
            object_provides=IEvent,
            shared_calendar=self.calendar.UID(),
        )
        self.assertListEqual([self.event.UID()], [brain.UID for brain in brains])

    @pi_api.events.notifications_disabled
    def test_delete_central_calendar(self):
        api.content.delete(obj=self.calendar)
        self.assertIsNone(self.event.shared_calendar)
        self.assertEqual(api.content.get_state(self.event), "published")

    def test_get_central_calendars(self):
        view = CalendarAppView(self.portal.apps.calendar, self.request)
        calendars = view.get_central_calendars()
        self.assertIn(self.calendar.UID(), [c.UID for c in calendars])

    def test_adapter_calendar_event_component(self):
        event = api.content.create(
            container=self.portal, description="fòò", type="Event", id="event1"
        )
        self.assertDictEqual(
            IICalendarEventComponent(event).description,
            {"value": "fòò\nhttp://nohost/plone/event1"},
        )


TEST_ICS = """
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Plone.org//NONSGML plone.app.event//EN
X-WR-CALDESC:this is a test description
X-WR-CALNAME:testevent
X-WR-RELCALID:48f1a7ad64e847568d860cd092344970
X-WR-TIMEZONE:Europe/Vienna
BEGIN:VTIMEZONE
TZID:Europe/Vienna
X-LIC-LOCATION:Europe/Vienna
BEGIN:DAYLIGHT
DTSTART;VALUE=DATE-TIME:20130331T030000
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
END:DAYLIGHT
END:VTIMEZONE

BEGIN:VEVENT
SUMMARY:e1
DESCRIPTION:A bäsic event with many pråperties.
DTSTART;TZID=Europe/Vienna;VALUE=DATE-TIME:20130719T120000
DTEND;TZID=Europe/Vienna;VALUE=DATE-TIME:20130720T130000
DTSTAMP;VALUE=DATE-TIME:20130719T125936Z
UID:48f1a7ad64e847568d860cd092344970
ATTENDEE;CN=attendee1;ROLE=REQ-PARTICIPANT:attendee1
ATTENDEE;CN=attendee2;ROLE=REQ-PARTICIPANT:attendee2
ATTENDEE;CN=attendee3;ROLE=REQ-PARTICIPANT:attendee3
CONTACT:Tést Contact Näme, 1234, test@contact.email, http://test.url
CREATED;VALUE=DATE-TIME:20130719T105931Z
LAST-MODIFIED;VALUE=DATE-TIME:20130719T105931Z
LOCATION:Optimolwerke, Friedenstraße, Munich, Germany
URL:http://localhost:8080/Plone/testevent
END:VEVENT

BEGIN:VEVENT
SUMMARY:e2
DESCRIPTION:A recurring event with exdates
DTSTART:19960401T010000
DTEND:19960401T020000
RRULE:FREQ=DAILY;COUNT=100
EXDATE:19960402T010000Z,19960403T010000Z,19960404T010000Z
UID:48f1a7ad64e847568d860cd0923449702
LAST-MODIFIED;VALUE=DATE-TIME:20130719T105931Z
END:VEVENT

BEGIN:VEVENT
SUMMARY:e3
DESCRIPTION:A Recurring event with multiple exdates, one per line.
DTSTART;TZID=Europe/Vienna:20120327T100000
DTEND;TZID=Europe/Vienna:20120327T180000
RRULE:FREQ=WEEKLY;UNTIL=20120703T080000Z;BYDAY=TU
EXDATE;TZID=Europe/Vienna:20120529T100000
EXDATE;TZID=Europe/Vienna:20120403T100000
EXDATE;TZID=Europe/Vienna:20120410T100000
EXDATE;TZID=Europe/Vienna:20120501T100000
EXDATE;TZID=Europe/Vienna:20120417T100000
DTSTAMP:20130716T120638Z
UID:48f1a7ad64e847568d860cd0923449703
LAST-MODIFIED;VALUE=DATE-TIME:20130719T105931Z
END:VEVENT

BEGIN:VEVENT
SUMMARY:e4
DESCRIPTION:Whole day event
DTSTART:20130404
DTEND:20130404
UID:48f1a7ad64e847568d860cd0923449704
LAST-MODIFIED;VALUE=DATE-TIME:20130719T105931Z
END:VEVENT

BEGIN:VEVENT
SUMMARY:e5
DESCRIPTION:Open end event
DTSTART:20130402T120000
UID:48f1a7ad64e847568d860cd0923449705
LAST-MODIFIED;VALUE=DATE-TIME:20130719T105931Z
END:VEVENT

END:VCALENDAR
"""
