#! /usr/bin/python
# Copyright (c) 2014 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.

# This module provides functions for caller to retrieve a job's history,
# including special tasks executed before and after the job, and each steps
# start/end time.

import argparse
import datetime as datetime_base

import common
from autotest_lib.client.common_lib import global_config
from autotest_lib.frontend import setup_django_environment
from autotest_lib.frontend.afe import models
from autotest_lib.frontend.tko import models as tko_models

CONFIG = global_config.global_config
AUTOTEST_SERVER = CONFIG.get_config_value('SERVER', 'hostname', type=str)

LOG_BASE_URL = 'http://%s/tko/retrieve_logs.cgi?job=/results/' % AUTOTEST_SERVER
JOB_URL = LOG_BASE_URL + '%(job_id)s-%(owner)s/%(hostname)s'
LOG_PATH_FMT = 'hosts/%(hostname)s/%(task_id)d-%(taskname)s'
TASK_URL = LOG_BASE_URL + LOG_PATH_FMT
AUTOSERV_DEBUG_LOG = 'debug/autoserv.DEBUG'

# Add some buffer before and after job start/end time when searching for special
# tasks. This is to guarantee to include reset before the job starts and repair
# and cleanup after the job finishes.
TIME_BUFFER = datetime_base.timedelta(hours=2)


class JobHistoryObject(object):
    """A common interface to call get_history to return a dictionary of the
    object's history record, e.g., start/end time.
    """

    def build_history_entry(self):
        """Build a history entry.

        This function expect the object has required attributes. Any missing
        attributes will lead to failure.

        @return: A dictionary as the history entry of given job/task.
        """
        return  {'id': self.id,
                 'name': self.name,
                 'hostname': self.hostname,
                 'status': self.status,
                 'log_url': self.log_url,
                 'autoserv_log_url': self.autoserv_log_url,
                 'start_time': self.start_time,
                 'end_time': self.end_time,
                 'time_used': self.time_used,
                 }


    def get_history(self):
        """Return a list of dictionaries of select job/task's history.
        """
        raise NotImplementedError('You must override this method in child '
                                  'class.')


class SpecialTaskInfo(JobHistoryObject):
    """Information of a special task.

    Its properties include:
        id: Special task ID.
        task: An AFE models.SpecialTask object.
        hostname: hostname of the DUT that runs the special task.
        log_url: Url to debug log.
        autoserv_log_url: Url to the autoserv log.
    """

    def __init__(self, task):
        """Constructor

        @param task: An AFE models.SpecialTask object, which has the information
                     of the special task from database.
        """
        # Special task ID
        self.id = task.id
        # AFE special_task model
        self.task = task
        self.name = task.task
        self.hostname = task.host.hostname
        self.status = task.status

        # Link to log
        task_info = {'task_id': task.id, 'taskname': task.task.lower(),
                     'hostname': self.hostname}
        self.log_url = TASK_URL % task_info
        self.autoserv_log_url = '%s/%s' % (self.log_url, AUTOSERV_DEBUG_LOG)

        self.start_time = self.task.time_started
        self.end_time = self.task.time_finished
        if self.start_time and self.end_time:
            self.time_used = (self.end_time - self.start_time).total_seconds()
        else:
            self.time_used = None


    def __str__(self):
        """Get a formatted string of the details of the task info.
        """
        return ('Task %d: %s from %s to %s, for %s seconds.\n' %
                (self.id, self.task.task, self.start_time, self.end_time,
                 self.time_used))


    def get_history(self):
        """Return a dictionary of selected object properties.
        """
        return [self.build_history_entry()]


class TaskCacheCollection(dict):
    """A cache to hold tasks for multiple hosts.

    It's a dictionary of host_id: TaskCache.
    """

    def try_get(self, host_id, job_id, start_time, end_time):
        """Try to get tasks from cache.

        @param host_id: ID of the host.
        @param job_id: ID of the test job that's related to the special task.
        @param start_time: Start time to search for special task.
        @param end_time: End time to search for special task.
        @return: The list of special tasks that are related to given host and
                 Job id. Note that, None means the cache is not available.
                 However, [] means no special tasks found in cache.
        """
        if not host_id in self:
            return None
        return self[host_id].try_get(job_id, start_time, end_time)


    def update(self, host_id, start_time, end_time):
        """Update the cache of the given host by searching database.

        @param host_id: ID of the host.
        @param start_time: Start time to search for special task.
        @param end_time: End time to search for special task.
        """
        search_start_time = start_time - TIME_BUFFER
        search_end_time = end_time + TIME_BUFFER
        tasks = models.SpecialTask.objects.filter(
                host_id=host_id,
                time_started__gte=search_start_time,
                time_started__lte=search_end_time)
        self[host_id] = TaskCache(tasks, search_start_time, search_end_time)


class TaskCache(object):
    """A cache that hold tasks for a host.
    """

    def __init__(self, tasks=[], start_time=None, end_time=None):
        """Constructor
        """
        self.tasks = tasks
        self.start_time = start_time
        self.end_time = end_time

    def try_get(self, job_id, start_time, end_time):
        """Try to get tasks from cache.

        @param job_id: ID of the test job that's related to the special task.
        @param start_time: Start time to search for special task.
        @param end_time: End time to search for special task.
        @return: The list of special tasks that are related to the job id.
                 Note that, None means the cache is not available.
                 However, [] means no special tasks found in cache.
        """
        if start_time < self.start_time or end_time > self.end_time:
            return None
        return [task for task in self.tasks if task.queue_entry and
                task.queue_entry.job.id == job_id]


class TestJobInfo(JobHistoryObject):
    """Information of a test job
    """

    def __init__(self, hqe, task_caches=None, suite_start_time=None,
                 suite_end_time=None):
        """Constructor

        @param hqe: HostQueueEntry of the job.
        @param task_caches: Special tasks that's from a previous query.
        @param suite_start_time: Start time of the suite job, default is
                None. Used to build special task search cache.
        @param suite_end_time: End time of the suite job, default is
                None. Used to build special task search cache.
        """
        # AFE job ID
        self.id = hqe.job.id
        # AFE job model
        self.job = hqe.job
        # Name of the job, strip all build and suite info.
        self.name = hqe.job.name.split('/')[-1]
        self.status = hqe.status if hqe else None

        try:
            self.tko_job = tko_models.Job.objects.filter(afe_job_id=self.id)[0]
            self.host = models.Host.objects.filter(
                    hostname=self.tko_job.machine.hostname)[0]
            self.hostname = self.tko_job.machine.hostname
            self.start_time = self.tko_job.started_time
            self.end_time = self.tko_job.finished_time
        except IndexError:
            # The test job was never started.
            self.tko_job = None
            self.host = None
            self.hostname = None
            self.start_time = None
            self.end_time = None

        if self.end_time and self.start_time:
            self.time_used = (self.end_time - self.start_time).total_seconds()
        else:
            self.time_used = None

        # Link to log
        self.log_url = JOB_URL % {'job_id': hqe.job.id, 'owner': hqe.job.owner,
                                  'hostname': self.hostname}
        self.autoserv_log_url = '%s/%s' % (self.log_url, AUTOSERV_DEBUG_LOG)

        self._get_special_tasks(hqe, task_caches, suite_start_time,
                                suite_end_time)


    def _get_special_tasks(self, hqe, task_caches=None, suite_start_time=None,
                           suite_end_time=None):
        """Get special tasks ran before and after the test job.

        @param hqe: HostQueueEntry of the job.
        @param task_caches: Special tasks that's from a previous query.
        @param suite_start_time: Start time of the suite job, default is
                None. Used to build special task search cache.
        @param suite_end_time: End time of the suite job, default is
                None. Used to build special task search cache.
        """
        # Special tasks run before job starts.
        self.tasks_before = []
        # Special tasks run after job finished.
        self.tasks_after = []

        # Skip locating special tasks if hqe is None, or not started yet, as
        # that indicates the test job might not be started.
        if not hqe or not hqe.started_on:
            return

        # Assume special tasks for the test job all start within 2 hours
        # before the test job starts or 2 hours after the test finishes. In most
        # cases, special task won't take longer than 2 hours to start before
        # test job starts and after test job finishes.
        search_start_time = hqe.started_on - TIME_BUFFER
        search_end_time = (hqe.finished_on + TIME_BUFFER if hqe.finished_on else
                           hqe.started_on + TIME_BUFFER)

        if task_caches is not None and suite_start_time and suite_end_time:
            tasks = task_caches.try_get(self.host.id, self.id,
                                        suite_start_time, suite_end_time)
            if tasks is None:
                task_caches.update(self.host.id, search_start_time,
                                   search_end_time)
                tasks = task_caches.try_get(self.host.id, self.id,
                                            suite_start_time, suite_end_time)
        else:
            tasks = models.SpecialTask.objects.filter(
                        host_id=self.host.id,
                        time_started__gte=search_start_time,
                        time_started__lte=search_end_time)
            tasks = [task for task in tasks if task.queue_entry and
                     task.queue_entry.job.id == self.id]

        for task in tasks:
            task_info = SpecialTaskInfo(task)
            if task.time_started < self.start_time:
                self.tasks_before.append(task_info)
            else:
                self.tasks_after.append(task_info)


    def get_history(self):
        """Get the history of a test job.

        @return: A list of special tasks and test job information.
        """
        history = []
        history.extend([task.build_history_entry() for task in
                        self.tasks_before])
        history.append(self.build_history_entry())
        history.extend([task.build_history_entry() for task in
                        self.tasks_after])
        return history


    def __str__(self):
        """Get a formatted string of the details of the job info.
        """
        result = '%d: %s\n' % (self.id, self.name)
        for task in self.tasks_before:
            result += str(task)

        result += ('Test from %s to %s, for %s seconds.\n' %
                   (self.start_time, self.end_time, self.time_used))

        for task in self.tasks_after:
            result += str(task)

        return result


class SuiteJobInfo(JobHistoryObject):
    """Information of a suite job
    """

    def __init__(self, hqe):
        """Constructor

        @param hqe: HostQueueEntry of the job.
        """
        # AFE job ID
        self.id = hqe.job.id
        # AFE job model
        self.job = hqe.job
        # Name of the job, strip all build and suite info.
        self.name = hqe.job.name.split('/')[-1]
        self.status = hqe.status if hqe else None

        self.log_url = JOB_URL % {'job_id': hqe.job.id, 'owner': hqe.job.owner,
                                  'hostname': 'hostless'}

        hqe = models.HostQueueEntry.objects.filter(job_id=hqe.job.id)[0]
        self.start_time = hqe.started_on
        self.end_time = hqe.finished_on
        if self.start_time and self.end_time:
            self.time_used = (self.end_time - self.start_time).total_seconds()
        else:
            self.time_used = None

        # Cache of special tasks, hostname: ((start_time, end_time), [tasks])
        task_caches = TaskCacheCollection()
        self.test_jobs = []
        for job in models.Job.objects.filter(parent_job_id=self.id):
            try:
                job_hqe = models.HostQueueEntry.objects.filter(job_id=job.id)[0]
            except IndexError:
                continue
            self.test_jobs.append(TestJobInfo(job_hqe, task_caches,
                                                self.start_time, self.end_time))


    def get_history(self):
        """Get the history of a suite job.

        @return: A list of special tasks and test job information that has
                 suite job as the parent job.
        """
        history = []
        for job in sorted(self.test_jobs,
                          key=lambda j: (j.hostname, j.start_time)):
            history.extend(job.get_history())
        return history


    def __str__(self):
        """Get a formatted string of the details of the job info.
        """
        result = '%d: %s\n' % (self.id, self.name)
        for job in self.test_jobs:
            result += str(job)
            result += '-' * 80 + '\n'
        return result


def get_job_info(job_id):
    """Get the history of a job.

    @param job_id: ID of the job.
    @return: A TestJobInfo object that contains the test job and its special
             tasks' start/end time, if the job is a test job. Otherwise, return
             a SuiteJobInfo object if the job is a suite job.
    @raise Exception: if the test job can't be found in database.
    """
    try:
        hqe = models.HostQueueEntry.objects.filter(job_id=job_id)[0]
    except IndexError:
        raise Exception('No HQE found for job ID %d' % job_id)

    if hqe and hqe.execution_subdir != 'hostless':
        return TestJobInfo(hqe)
    else:
        return SuiteJobInfo(hqe)


def main():
    """Main script.

    The script accepts a job ID and print out the test job and its special
    tasks' start/end time.
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('--job_id', type=int, dest='job_id', required=True)
    options = parser.parse_args()

    job_info = get_job_info(options.job_id)

    print job_info


if __name__ == '__main__':
    main()
