# 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
import logging

import common
from autotest_lib.client.common_lib import priorities

import base_event
import 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.
    """

    # Number of days between each timed event to trigger. Default to 1.
    DAYS_INTERVAL = 1


    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 super(TimedEvent, self).ShouldHandle():
            return True
        else:
            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]}
        """
        since_date = self._deadline - datetime.timedelta(days=days_ago)
        all_branch_manifests = self._mv.ManifestsSinceDate(since_date, 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


    def _LatestLaunchControlBuildsSince(self, board, days_ago):
        """Get per-branch, per-board builds since last run of this event.

        @param board: the board whose builds we want, e.g., android-shamu.
        @param days_ago: how many days back to look for manifests.

        @return: A list of Launch Control builds for the given board, e.g.,
                ['git_mnc_release/shamu-eng/123',
                 'git_mnc_release/shamu-eng/124'].
        """
        # TODO(crbug.com/589936): Get the latest builds for Launch Control for a
        # given period, not just the last build on each branch.
        return self._LatestLaunchControlBuilds(board)


    def GetBranchBuildsForBoard(self, board):
        """Get per-branch, per-board builds since last run of this event.
        """
        return self._LatestPerBranchBuildsSince(board, self.DAYS_INTERVAL)


    def GetLaunchControlBuildsForBoard(self, board):
        """Get per-branch, per-board builds since last run of this event.

        @param board: the board whose builds we want.

        @return: A list of Launch Control builds for the given board, e.g.,
                ['git_mnc_release/shamu-eng/123',
                 'git_mnc_release/shamu-eng/124'].
        """
        return self._LatestLaunchControlBuildsSince(board, self.DAYS_INTERVAL)


class Nightly(TimedEvent):
    """A TimedEvent that allows a task to be triggered at every night. Each task
    can set the hour when it should be triggered, through `hour` setting.

    @var KEYWORD: the keyword to use in a run_on option to associate a task
                  with the Nightly event.
    @var _DEFAULT_HOUR: the default hour to trigger the nightly event.
    """

    # Nightly event is triggered once a day.
    DAYS_INTERVAL = 1

    KEYWORD = 'nightly'
    # Each task may have different setting of `hour`. Therefore, nightly tasks
    # can run at each hour. The default is set to 9PM.
    _DEFAULT_HOUR = 21
    PRIORITY = priorities.Priority.DAILY
    TIMEOUT = 24  # Kicked off once a day, so they get the full day to run

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

        @param manifest_versions: ManifestVersions instance to use for querying.
        @param always_handle: If True, make ShouldHandle() always return True.
        """
        # Set the deadline to the next even hour.
        now = self._now()
        now_hour = datetime.datetime(now.year, now.month, now.day, now.hour)
        extra_hour = 0 if now == now_hour else 1
        deadline = now_hour + datetime.timedelta(hours=extra_hour)
        super(Nightly, self).__init__(self.KEYWORD, manifest_versions,
                                      always_handle, deadline)


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


    def FilterTasks(self):
        """Filter the tasks to only return tasks that should run now.

        Nightly task can run at each hour. This function only return the tasks
        set to run in current hour.

        @return: A list of tasks that can run now.
        """
        current_hour = self._now().hour
        return [task for task in self.tasks
                if ((task.hour is not None and task.hour == current_hour) or
                    (task.hour is None and
                     current_hour == self._DEFAULT_HOUR))]


class Weekly(TimedEvent):
    """A TimedEvent that allows a task to be triggered at every week. Each task
    can set the day when it should be triggered, through `day` setting.

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

    # Weekly event is triggered once a week.
    DAYS_INTERVAL = 7

    KEYWORD = 'weekly'
    _DEFAULT_DAY = 5  # Saturday
    _DEFAULT_HOUR = 23
    PRIORITY = priorities.Priority.WEEKLY
    TIMEOUT = 7 * 24  # 7 days


    @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(Weekly, 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 this week's event and set the
        # next deadline for this suite appropriately.
        now = self._now()
        this_week_deadline = datetime.datetime.combine(
                now, datetime.time(event_time))
        if this_week_deadline >= now:
            deadline = this_week_deadline
        else:
            deadline = this_week_deadline + datetime.timedelta(days=1)
        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 instance.
        """
        super(Weekly, self).Merge(to_merge)
        if self._deadline.time() != to_merge._deadline.time():
            self._deadline = to_merge._deadline


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


    def FilterTasks(self):
        """Filter the tasks to only return tasks that should run now.

        Weekly task can be scheduled at any day of the week. This function only
        return the tasks set to run in current day.

        @return: A list of tasks that can run now.
        """
        current_day = self._now().weekday()
        return [task for task in self.tasks
                if ((task.day is not None and task.day == current_day) or
                    (task.day is None and current_day == self._DEFAULT_DAY))]
