#!/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.

"""Runs on autotest servers from a cron job to self update them.

This script is designed to run on all autotest servers to allow them to
automatically self-update based on the manifests used to create their (existing)
repos.
"""

from __future__ import print_function

import ConfigParser
import argparse
import os
import re
import subprocess
import socket
import sys
import time

import common

from autotest_lib.client.common_lib import global_config
from autotest_lib.server import utils as server_utils
from autotest_lib.server.cros.dynamic_suite import frontend_wrappers


# How long after restarting a service do we watch it to see if it's stable.
SERVICE_STABILITY_TIMER = 60

# A dict to map update_commands defined in config file to repos or files that
# decide whether need to update these commands. E.g. if no changes under
# frontend repo, no need to update afe.
COMMANDS_TO_REPOS_DICT = {'afe': 'frontend/client/',
                          'tko': 'frontend/client/'}
BUILD_EXTERNALS_COMMAND = 'build_externals'

_RESTART_SERVICES_FILE = os.path.join(os.environ['HOME'],
                                      'push_restart_services')

AFE = frontend_wrappers.RetryingAFE(
        server=server_utils.get_global_afe_hostname(), timeout_min=5,
        delay_sec=10)
HOSTNAME = socket.gethostname()

class DirtyTreeException(Exception):
    """Raised when the tree has been modified in an unexpected way."""


class UnknownCommandException(Exception):
    """Raised when we try to run a command name with no associated command."""


class UnstableServices(Exception):
    """Raised if a service appears unstable after restart."""


def strip_terminal_codes(text):
    """This function removes all terminal formatting codes from a string.

    @param text: String of text to cleanup.
    @returns String with format codes removed.
    """
    ESC = '\x1b'
    return re.sub(ESC+r'\[[^m]*m', '', text)


def _clean_pyc_files():
    print('Removing .pyc files')
    try:
        subprocess.check_output([
                'find', '.',
                '(',
                # These are ignored to reduce IO load (crbug.com/759780).
                '-path', './site-packages',
                '-o', '-path', './containers',
                '-o', '-path', './logs',
                '-o', '-path', './results',
                ')',
                '-prune',
                '-o', '-name', '*.pyc',
                '-exec', 'rm', '-f', '{}', '+'])
    except Exception as e:
        print('Warning: fail to remove .pyc! %s' % e)


def verify_repo_clean():
    """This function cleans the current repo then verifies that it is valid.

    @raises DirtyTreeException if the repo is still not clean.
    @raises subprocess.CalledProcessError on a repo command failure.
    """
    subprocess.check_output(['git', 'stash', '-u'])
    subprocess.check_output(['git', 'stash', 'clear'])
    out = subprocess.check_output(['repo', 'status'], stderr=subprocess.STDOUT)
    out = strip_terminal_codes(out).strip()

    if not 'working directory clean' in out and not 'working tree clean' in out:
        raise DirtyTreeException('%s repo not clean: %s' % (HOSTNAME, out))


def _clean_externals():
    """Clean untracked files within ExternalSource and site-packages/

    @raises subprocess.CalledProcessError on a git command failure.
    """
    dirs_to_clean = ['site-packages/', 'ExternalSource/']
    cmd = ['git', 'clean', '-fxd'] + dirs_to_clean
    subprocess.check_output(cmd)


def repo_versions():
    """This function collects the versions of all git repos in the general repo.

    @returns A dictionary mapping project names to git hashes for HEAD.
    @raises subprocess.CalledProcessError on a repo command failure.
    """
    cmd = ['repo', 'forall', '-p', '-c', 'pwd && git log -1 --format=%h']
    output = strip_terminal_codes(subprocess.check_output(cmd))

    # The expected output format is:

    # project chrome_build/
    # /dir/holding/chrome_build
    # 73dee9d
    #
    # project chrome_release/
    # /dir/holding/chrome_release
    # 9f3a5d8

    lines = output.splitlines()

    PROJECT_PREFIX = 'project '

    project_heads = {}
    for n in range(0, len(lines), 4):
        project_line = lines[n]
        project_dir = lines[n+1]
        project_hash = lines[n+2]
        # lines[n+3] is a blank line, but doesn't exist for the final block.

        # Convert 'project chrome_build/' -> 'chrome_build'
        assert project_line.startswith(PROJECT_PREFIX)
        name = project_line[len(PROJECT_PREFIX):].rstrip('/')

        project_heads[name] = (project_dir, project_hash)

    return project_heads


def repo_versions_to_decide_whether_run_cmd_update():
    """Collect versions of repos/files defined in COMMANDS_TO_REPOS_DICT.

    For the update_commands defined in config files, no need to run the command
    every time. Only run it when the repos/files related to the commands have
    been changed.

    @returns A set of tuples: {(cmd, repo_version), ()...}
    """
    results = set()
    for cmd, repo in COMMANDS_TO_REPOS_DICT.iteritems():
        version = subprocess.check_output(
                ['git', 'log', '-1', '--pretty=tformat:%h',
                 '%s/%s' % (common.autotest_dir, repo)])
        results.add((cmd, version.strip()))
    return results


def repo_sync(update_push_servers=False):
    """Perform a repo sync.

    @param update_push_servers: If True, then update test_push servers to ToT.
                                Otherwise, update server to prod branch.
    @raises subprocess.CalledProcessError on a repo command failure.
    """
    subprocess.check_output(['repo', 'sync', '--force-sync'])
    if update_push_servers:
        print('Updating push servers, checkout cros/master')
        subprocess.check_output(['git', 'checkout', 'cros/master'],
                                stderr=subprocess.STDOUT)
    else:
        print('Updating server to prod branch')
        subprocess.check_output(['git', 'checkout', 'cros/prod'],
                                stderr=subprocess.STDOUT)
    _clean_pyc_files()


def discover_update_commands():
    """Lookup the commands to run on this server.

    These commonly come from shadow_config.ini, since they vary by server type.

    @returns List of command names in string format.
    """
    try:
        return global_config.global_config.get_config_value(
                'UPDATE', 'commands', type=list)

    except (ConfigParser.NoSectionError, global_config.ConfigError):
        return []


def get_restart_services():
    """Find the services that need restarting on the current server.

    These commonly come from shadow_config.ini, since they vary by server type.

    @returns Iterable of service names in string format.
    """
    with open(_RESTART_SERVICES_FILE) as f:
        for line in f:
            yield line.rstrip()


def update_command(cmd_tag, dryrun=False, use_chromite_master=False):
    """Restart a command.

    The command name is looked up in global_config.ini to find the full command
    to run, then it's executed.

    @param cmd_tag: Which command to restart.
    @param dryrun: If true print the command that would have been run.
    @param use_chromite_master: True if updating chromite to master, rather
                                than prod.

    @raises UnknownCommandException If cmd_tag can't be looked up.
    @raises subprocess.CalledProcessError on a command failure.
    """
    # Lookup the list of commands to consider. They are intended to be
    # in global_config.ini so that they can be shared everywhere.
    cmds = dict(global_config.global_config.config.items(
        'UPDATE_COMMANDS'))

    if cmd_tag not in cmds:
        raise UnknownCommandException(cmd_tag, cmds)

    command = cmds[cmd_tag]
    # When updating push servers, pass an arg to build_externals to update
    # chromite to master branch for testing
    if use_chromite_master and cmd_tag == BUILD_EXTERNALS_COMMAND:
        command += ' --use_chromite_master'

    print('Running: %s: %s' % (cmd_tag, command))
    if dryrun:
        print('Skip: %s' % command)
    else:
        try:
            subprocess.check_output(command, shell=True,
                                    cwd=common.autotest_dir,
                                    stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            print('FAILED %s :' % HOSTNAME)
            print(e.output)
            raise


def restart_service(service_name, dryrun=False):
    """Restart a service.

    Restarts the standard service with "service <name> restart".

    @param service_name: The name of the service to restart.
    @param dryrun: Don't really run anything, just print out the command.

    @raises subprocess.CalledProcessError on a command failure.
    """
    cmd = ['sudo', 'service', service_name, 'restart']
    print('Restarting: %s' % service_name)
    if dryrun:
        print('Skip: %s' % ' '.join(cmd))
    else:
        subprocess.check_call(cmd, stderr=subprocess.STDOUT)


def service_status(service_name):
    """Return the results "status <name>" for a given service.

    This string is expected to contain the pid, and so to change is the service
    is shutdown or restarted for any reason.

    @param service_name: The name of the service to check on.

    @returns The output of the external command.
             Ex: autofs start/running, process 1931

    @raises subprocess.CalledProcessError on a command failure.
    """
    return subprocess.check_output(['sudo', 'service', service_name, 'status'])


def restart_services(service_names, dryrun=False, skip_service_status=False):
    """Restart services as needed for the current server type.

    Restart the listed set of services, and watch to see if they are stable for
    at least SERVICE_STABILITY_TIMER. It restarts all services quickly,
    waits for that delay, then verifies the status of all of them.

    @param service_names: The list of service to restart and monitor.
    @param dryrun: Don't really restart the service, just print out the command.
    @param skip_service_status: Set to True to skip service status check.
                                Default is False.

    @raises subprocess.CalledProcessError on a command failure.
    @raises UnstableServices if any services are unstable after restart.
    """
    service_statuses = {}

    if dryrun:
        for name in service_names:
            restart_service(name, dryrun=True)
        return

    # Restart each, and record the status (including pid).
    for name in service_names:
        restart_service(name)

    # Skip service status check if --skip-service-status is specified. Used for
    # servers in backup status.
    if skip_service_status:
        print('--skip-service-status is specified, skip checking services.')
        return

    # Wait for a while to let the services settle.
    time.sleep(SERVICE_STABILITY_TIMER)
    service_statuses = {name: service_status(name) for name in service_names}
    time.sleep(SERVICE_STABILITY_TIMER)
    # Look for any services that changed status.
    unstable_services = [n for n in service_names
                         if service_status(n) != service_statuses[n]]

    # Report any services having issues.
    if unstable_services:
      raise UnstableServices('%s service restart failed: %s' %
                             (HOSTNAME, unstable_services))


def run_deploy_actions(cmds_skip=set(), dryrun=False,
                       skip_service_status=False, use_chromite_master=False):
    """Run arbitrary update commands specified in global.ini.

    @param cmds_skip: cmds no need to run since the corresponding repo/file
                      does not change.
    @param dryrun: Don't really restart the service, just print out the command.
    @param skip_service_status: Set to True to skip service status check.
                                Default is False.
    @param use_chromite_master: True if updating chromite to master, rather
                                than prod.

    @raises subprocess.CalledProcessError on a command failure.
    @raises UnstableServices if any services are unstable after restart.
    """
    defined_cmds = set(discover_update_commands())
    cmds = defined_cmds - cmds_skip
    if cmds:
        print('Running update commands:', ', '.join(cmds))
        for cmd in cmds:
            update_command(cmd, dryrun=dryrun,
                           use_chromite_master=use_chromite_master)

    services = list(get_restart_services())
    if services:
        print('Restarting Services:', ', '.join(services))
        restart_services(services, dryrun=dryrun,
                         skip_service_status=skip_service_status)


def report_changes(versions_before, versions_after):
    """Produce a report describing what changed in all repos.

    @param versions_before: Results of repo_versions() from before the update.
    @param versions_after: Results of repo_versions() from after the update.

    @returns string containing a human friendly changes report.
    """
    result = []

    if versions_after:
        for project in sorted(set(versions_before.keys() + versions_after.keys())):
            result.append('%s:' % project)

            _, before_hash = versions_before.get(project, (None, None))
            after_dir, after_hash = versions_after.get(project, (None, None))

            if project not in versions_before:
                result.append('Added.')

            elif project not in versions_after:
                result.append('Removed.')

            elif before_hash == after_hash:
                result.append('No Change.')

            else:
                hashes = '%s..%s' % (before_hash, after_hash)
                cmd = ['git', 'log', hashes, '--oneline']
                out = subprocess.check_output(cmd, cwd=after_dir,
                                              stderr=subprocess.STDOUT)
                result.append(out.strip())

            result.append('')
    else:
        for project in sorted(versions_before.keys()):
            _, before_hash = versions_before[project]
            result.append('%s: %s' % (project, before_hash))
        result.append('')

    return '\n'.join(result)


def parse_arguments(args):
    """Parse command line arguments.

    @param args: The command line arguments to parse. (ususally sys.argsv[1:])

    @returns An argparse.Namespace populated with argument values.
    """
    parser = argparse.ArgumentParser(
            description='Command to update an autotest server.')
    parser.add_argument('--skip-verify', action='store_false',
                        dest='verify', default=True,
                        help='Disable verification of a clean repository.')
    parser.add_argument('--skip-update', action='store_false',
                        dest='update', default=True,
                        help='Skip the repository source code update.')
    parser.add_argument('--skip-actions', action='store_false',
                        dest='actions', default=True,
                        help='Skip the post update actions.')
    parser.add_argument('--skip-report', action='store_false',
                        dest='report', default=True,
                        help='Skip the git version report.')
    parser.add_argument('--actions-only', action='store_true',
                        help='Run the post update actions (restart services).')
    parser.add_argument('--dryrun', action='store_true',
                        help='Don\'t actually run any commands, just log.')
    parser.add_argument('--skip-service-status', action='store_true',
                        help='Skip checking the service status.')
    parser.add_argument('--update_push_servers', action='store_true',
                        help='Indicate to update test_push server. If not '
                             'specify, then update server to production.')
    parser.add_argument('--force-clean-externals', action='store_true',
                        default=False,
                        help='Force a cleanup of all untracked files within '
                             'site-packages/ and ExternalSource/, so that '
                             'build_externals will build from scratch.')
    parser.add_argument('--force_update', action='store_true',
                        help='Force to run the update commands for afe, tko '
                             'and build_externals')

    results = parser.parse_args(args)

    if results.actions_only:
        results.verify = False
        results.update = False
        results.report = False

    # TODO(dgarrett): Make these behaviors support dryrun.
    if results.dryrun:
        results.verify = False
        results.update = False
        results.force_clean_externals = False

    if not results.update_push_servers:
      print('Will skip service check for pushing servers in prod.')
      results.skip_service_status = True
    return results


class ChangeDir(object):

    """Context manager for changing to a directory temporarily."""

    def __init__(self, dir):
        self.new_dir = dir
        self.old_dir = None

    def __enter__(self):
        self.old_dir = os.getcwd()
        os.chdir(self.new_dir)

    def __exit__(self, exc_type, exc_val, exc_tb):
        os.chdir(self.old_dir)


def _sync_chromiumos_repo():
    """Update ~chromeos-test/chromiumos repo."""
    print('Updating ~chromeos-test/chromiumos')
    with ChangeDir(os.path.expanduser('~chromeos-test/chromiumos')):
        ret = subprocess.call(['repo', 'sync', '--force-sync'],
                              stderr=subprocess.STDOUT)
        _clean_pyc_files()
    if ret != 0:
        print('Update failed, exited with status: %d' % ret)


def main(args):
    """Main method."""
    # Be careful before you change this call to `os.chdir()`:
    # We make several calls to `subprocess.check_output()` and
    # friends that depend on this directory, most notably calls to
    # the 'repo' command from `verify_repo_clean()`.
    os.chdir(common.autotest_dir)
    global_config.global_config.parse_config_file()

    behaviors = parse_arguments(args)
    print('Updating server: %s' % HOSTNAME)
    if behaviors.verify:
        print('Checking tree status:')
        verify_repo_clean()
        print('Tree status: clean')

    if behaviors.force_clean_externals:
       print('Cleaning all external packages and their cache...')
       _clean_externals()
       print('...done.')

    versions_before = repo_versions()
    versions_after = set()
    cmd_versions_before = repo_versions_to_decide_whether_run_cmd_update()
    cmd_versions_after = set()

    if behaviors.update:
        print('Updating Repo.')
        repo_sync(behaviors.update_push_servers)
        versions_after = repo_versions()
        cmd_versions_after = repo_versions_to_decide_whether_run_cmd_update()
        _sync_chromiumos_repo()

    if behaviors.actions:
        # If the corresponding repo/file not change, no need to run the cmd.
        cmds_skip = (set() if behaviors.force_update else
                     {t[0] for t in cmd_versions_before & cmd_versions_after})
        run_deploy_actions(
                cmds_skip, behaviors.dryrun, behaviors.skip_service_status,
                use_chromite_master=behaviors.update_push_servers)

    if behaviors.report:
        print('Changes:')
        print(report_changes(versions_before, versions_after))


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
