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

import common
from autotest_lib.client.common_lib import error
from autotest_lib.server import site_utils
from autotest_lib.server.cros.dynamic_suite import frontend_wrappers, reporting

class DedupingSchedulerException(Exception):
    """Base class for exceptions from this module."""
    pass


class ScheduleException(DedupingSchedulerException):
    """Raised when an error is returned from the AFE during scheduling."""
    pass


class DedupException(DedupingSchedulerException):
    """Raised when an error occurs while checking for duplicate jobs."""
    pass


class DedupingScheduler(object):
    """A class that will schedule suites to run on a given board, build.

    Includes logic to check whether or not a given (suite, board, build)
    has already been run.  If so, it will skip scheduling that suite.

    @var _afe: a frontend.AFE instance used to talk to autotest.
    """


    def __init__(self, afe=None, file_bug=False):
        """Constructor

        @param afe: an instance of AFE as defined in server/frontend.py.
                    Defaults to a frontend_wrappers.RetryingAFE instance.
        """
        self._afe = afe or frontend_wrappers.RetryingAFE(timeout_min=30,
                                                         delay_sec=10,
                                                         debug=False)
        self._file_bug = file_bug


    def _ShouldScheduleSuite(self, suite, board, build):
        """Return True if |suite| has not yet been run for |build| on |board|.

        True if |suite| has not been run for |build| on |board|, and
        the lab is open for this particular request.  False otherwise.

        @param suite: the name of the suite to run, e.g. 'bvt'
        @param board: the board to run the suite on, e.g. x86-alex
        @param build: the build to install e.g.
                      x86-alex-release/R18-1655.0.0-a1-b1584.
        @return False if the suite was already scheduled, True if not
        @raise DedupException if the AFE raises while searching for jobs.
        """
        try:
            site_utils.check_lab_status(build)
        except site_utils.TestLabException as ex:
            logging.debug('Skipping suite %s, board %s, build %s:  %s',
                          suite, board, build, str(ex))
            return False
        try:
            return not self._afe.get_jobs(name__startswith=build,
                                          name__endswith='control.'+suite)
        except Exception as e:
            raise DedupException(e)


    # TODO(fdeng): Add status='Available' back into the bug submittal;
    # right now it will be marked as Unconfirmed.
    def _ReportBug(self, title, description):
        """File a bug using bug reporter.

        @param title: A string, representing the bug title.
        @param description: A string, representing the bug description.
        @return: The id of the issue that was created,
                 or None if bug is not filed.
        """
        if not self._file_bug:
            return None
        lab_sheriff = site_utils.get_sheriffs(lab_only=True)
        logging.info('Filing a bug: %s', title)
        return reporting.submit_generic_bug_report(
            title=title,
            summary=description,
            cc=lab_sheriff,
            labels=['Hardware-lab'])


    def _Schedule(self, suite, board, build, pool, num, priority, timeout):
        """Schedule |suite|, if it hasn't already been run.

        @param suite: the name of the suite to run, e.g. 'bvt'
        @param board: the board to run the suite on, e.g. x86-alex
        @param build: the build to install e.g.
                      x86-alex-release/R18-1655.0.0-a1-b1584.
        @param pool: the pool of machines to use for scheduling purposes.
                     Default: None
        @param num: the number of devices across which to shard the test suite.
                    Type: integer or None
                    Default: None (uses sharding factor in global_config.ini).
        @param priority: One of the values from
                         client.common_lib.priorities.Priority.
        @param timeout: The max lifetime of the suite in hours.
        @return True if the suite got scheduled
        @raise ScheduleException if an error occurs while scheduling.
        """
        try:
            logging.info('Scheduling %s on %s against %s (pool: %s)',
                         suite, build, board, pool)
            if self._afe.run(
                        'create_suite_job', suite_name=suite, board=board,
                        build=build, check_hosts=False, num=num, pool=pool,
                        priority=priority, timeout=timeout,
                        wait_for_results=False) is not None:
                return True
            else:
                raise ScheduleException(
                    "Can't schedule %s for %s." % (suite, build))
        except (error.ControlFileNotFound, error.ControlFileEmpty,
                error.ControlFileMalformed, error.NoControlFileList) as e:
            title = ('Exception "%s" occurs when scheduling %s on '
                     '%s against %s (pool: %s)' %
                     (e.__class__.__name__, suite, build, board, pool))
            if self._ReportBug(title, str(e)) is None:
                # Raise the exception if not filing or failed to file a bug.
                raise ScheduleException(e)
            else:
                return False
        except Exception as e:
            raise ScheduleException(e)


    def ScheduleSuite(self, suite, board, build, pool, num, priority, timeout,
                      force=False):
        """Schedule |suite|, if it hasn't already been run.

        If |suite| has not already been run against |build| on |board|,
        schedule it and return True.  If it has, return False.

        @param suite: the name of the suite to run, e.g. 'bvt'
        @param board: the board to run the suite on, e.g. x86-alex
        @param build: the build to install e.g.
                      x86-alex-release/R18-1655.0.0-a1-b1584.
        @param pool: the pool of machines to use for scheduling purposes.
        @param num: the number of devices across which to shard the test suite.
                    Type: integer or None
        @param priority: One of the values from
                         client.common_lib.priorities.Priority.
        @param timeout: The max lifetime of the suite in hours.
        @param force: Always schedule the suite.
        @return True if the suite got scheduled, False if not
        @raise DedupException if we can't check for dups.
        @raise ScheduleException if the suite cannot be scheduled.
        """
        if force or self._ShouldScheduleSuite(suite, board, build):
            return self._Schedule(suite, board, build, pool, num, priority,
                                  timeout)
        return False


    def GetHosts(self, *args, **kwargs):
        """Forward a request to get hosts onto the AFE instance's get_hosts."""
        return self._afe.get_hosts(*args, **kwargs)
