# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import datetime, logging
import base_event, forgiving_config_parser, task


class TimedEvent(base_event.BaseEvent):
    """Base class for events that trigger based on time/day.

    @var _deadline: If this time has passed, ShouldHandle() returns True.
    """


    def __init__(self, keyword, manifest_versions, always_handle, deadline):
        """Constructor.

        @param keyword: the keyword/name of this event, e.g. nightly.
        @param manifest_versions: ManifestVersions instance to use for querying.
        @param always_handle: If True, make ShouldHandle() always return True.
        @param deadline: This instance's initial |_deadline|.
        """
        super(TimedEvent, self).__init__(keyword, manifest_versions,
                                         always_handle)
        self._deadline = deadline


    def __ne__(self, other):
        return self._deadline != other._deadline or self.tasks != other.tasks


    def __eq__(self, other):
        return self._deadline == other._deadline and self.tasks == other.tasks


    @staticmethod
    def _now():
        return datetime.datetime.now()


    def Prepare(self):
        pass


    def ShouldHandle(self):
        """Return True if self._deadline has passed; False if not."""
        if not super(TimedEvent, self).ShouldHandle():
            logging.info('Checking deadline %s for event %s',
                         self._deadline, self.keyword)
            return self._now() >= self._deadline


    def _LatestPerBranchBuildsSince(self, board, days_ago):
        """Get latest per-branch, per-board builds from last |days_ago| days.

        @param board: the board whose builds we want.
        @param days_ago: how many days back to look for manifests.
        @return {branch: [build-name]}
        """
        all_branch_manifests = self._mv.ManifestsSinceDays(days_ago, board)
        latest_branch_builds = {}
        for (type, milestone), manifests in all_branch_manifests.iteritems():
            build = base_event.BuildName(board, type, milestone, manifests[-1])
            latest_branch_builds[task.PickBranchName(type, milestone)] = [build]
        logging.info('%s event found candidate builds: %r',
                     self.keyword, latest_branch_builds)
        return latest_branch_builds


class Nightly(TimedEvent):
    """A TimedEvent that happens every night.

    @var KEYWORD: the keyword to use in a run_on option to associate a task
                  with the Nightly event.
    @var _DEFAULT_HOUR: can be overridden in the "nightly_params" config section
    """

    KEYWORD = 'nightly'
    _DEFAULT_HOUR = 21


    @classmethod
    def _ParseConfig(cls, config):
        """Create args to pass to __init__ by parsing |config|.

        Calls super class' _ParseConfig() method, then parses these additonal
        options:
          hour: Integer hour, on a 24 hour clock.
        """
        from_base = super(Nightly, cls)._ParseConfig(config)

        section = base_event.SectionName(cls.KEYWORD)
        event_time = config.getint(section, 'hour') or cls._DEFAULT_HOUR

        from_base.update({'event_time': event_time})
        return from_base


    def __init__(self, manifest_versions, always_handle, event_time):
        """Constructor.

        @param manifest_versions: ManifestVersions instance to use for querying.
        @param always_handle: If True, make ShouldHandle() always return True.
        @param event_time: The hour of the day to set |self._deadline| at.
        """
        # determine if we're past today's nightly event and set the
        # next deadline for this suite appropriately.
        now = self._now()
        tonight = datetime.datetime.combine(now, datetime.time(event_time))
        # tonight is now set to today at event_time:00:00
        if tonight >= now:
            deadline = tonight
        else:
            deadline = tonight + datetime.timedelta(days=1)
        super(Nightly, self).__init__(self.KEYWORD, manifest_versions,
                                      always_handle, deadline)


    def Merge(self, to_merge):
        """Merge this event with to_merge, changing some mutable properties.

        keyword remains unchanged; the following take on values from to_merge:
          _deadline iff the time of day in to_merge._deadline is different.

        @param to_merge: A TimedEvent instance to merge into this isntance.
        """
        super(TimedEvent, self).Merge(to_merge)
        if self._deadline.time() != to_merge._deadline.time():
            self._deadline = to_merge._deadline


    def GetBranchBuildsForBoard(self, board):
        return self._LatestPerBranchBuildsSince(board, 1)


    def UpdateCriteria(self):
        self._deadline = self._deadline + datetime.timedelta(days=1)


class Weekly(TimedEvent):
    """A TimedEvent that happens every week.

    @var KEYWORD: the keyword to use in a run_on option to associate a task
                  with the Weekly event.
    @var _DEFAULT_DAY: can be overridden in the "weekly_params" config section.
    @var _DEFAULT_HOUR: can be overridden in the "weekly_params" config section.
    """

    KEYWORD = 'weekly'
    _DEFAULT_DAY = 5  # Saturday
    _DEFAULT_HOUR = 23


    @classmethod
    def _ParseConfig(cls, config):
        """Create args to pass to __init__ by parsing |config|.

        Calls super class' _ParseConfig() method, then parses these additonal
        options:
          hour: Integer hour, on a 24 hour clock.
          day: Integer day, in a 0-indexed 7 day week, e.g. 5 == Saturday.
        """
        from_base = super(Weekly, cls)._ParseConfig(config)

        section = base_event.SectionName(cls.KEYWORD)
        event_time = config.getint(section, 'hour') or cls._DEFAULT_HOUR
        event_day = config.getint(section, 'day') or cls._DEFAULT_DAY

        from_base.update({'event_time': event_time, 'event_day': event_day})
        return from_base


    def __init__(self, manifest_versions, always_handle, event_day, event_time):
        """Constructor.

        @param manifest_versions: ManifestVersions instance to use for querying.
        @param always_handle: If True, make ShouldHandle() always return True.
        @param event_day: The day of the week to set |self._deadline| at.
        @param event_time: The hour of the day to set |self._deadline| at.
        """
        # determine if we're past this week's event and set the
        # next deadline for this suite appropriately.
        now = self._now()
        # Get a datetime representing this week's event_day
        # If now() is a Sunday, we 'add' 5 - 6 = -1 days to go back a day.
        # If now() is a Monday, we add 5 - 0 = 5 days to jump forward.
        this_week = now + datetime.timedelta(event_day-now.weekday())
        this_week_deadline = datetime.datetime.combine(
            this_week, datetime.time(event_time))
        if this_week_deadline >= now:
            deadline = this_week_deadline
        else:
            deadline = this_week_deadline + datetime.timedelta(days=7)
        super(Weekly, self).__init__(self.KEYWORD, manifest_versions,
                                     always_handle, deadline)


    def Merge(self, to_merge):
        """Merge this event with to_merge, changing some mutable properties.

        keyword remains unchanged; the following take on values from to_merge:
          _deadline iff the time of day in to_merge._deadline is different.

        @param to_merge: A TimedEvent instance to merge into this isntance.
        """
        super(TimedEvent, self).Merge(to_merge)
        if (self._deadline.time() != to_merge._deadline.time() or
            self._deadline.weekday() != to_merge._deadline.weekday()):
            self._deadline = to_merge._deadline


    def GetBranchBuildsForBoard(self, board):
        return self._LatestPerBranchBuildsSince(board, 7)


    def UpdateCriteria(self):
        self._deadline = self._deadline + datetime.timedelta(days=7)
