# Copyright (c) 2013 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 re

from autotest_lib.client.cros import constants
from autotest_lib.server import utils
from autotest_lib.server.cros import provision

try:
    from chromite.lib import metrics
except ImportError:
    metrics = utils.metrics_mock


LABEL_REGEX = r',.*:'
_LABEL_UPDATE_DURATION_METRIC = metrics.SecondsDistribution(
        'chromeos/autotest/provision/label_update_durations')

# job_labels should be a string like "name:setting,name:setting"
# However setting might also contain ',' therefore we need more advanced logic
# than split.
# non-provisionable labels are currently skipped, so they're safe to pass in.
job_labels = locals().get('job_labels') or ','.join(args)
labels_list = []
while job_labels:
    # Split based off of a comma followed by colon regex.
    split = re.split(LABEL_REGEX, job_labels)
    # First value found is a proper key value pair.
    labels_list.append(split[0].strip())
    # Remove this key value pair.
    job_labels = job_labels[len(split[0]):]
    # If a comma remains at the start of the remaining labels, remove it.
    # This should happen on every loop except the last one.
    if job_labels.startswith(','):
        job_labels = job_labels.lstrip(',')


def provision_machine(machine):
    """
    Run the appropriate provisioning tests to make the machine's labels match
    those given in job_labels.
    """
    job.record('START', None, 'provision')
    host = hosts.create_target_machine(machine, try_lab_servo=True)
    try:
        job.sysinfo.add_logdir(constants.AUTOUPDATE_PRESERVE_LOG)
        provision.run_special_task_actions(job, host, labels_list,
                                           provision.Provision)
        host.verify()

        # Let's update the labels on the host and track how long it takes.
        # Don't fail while updating the labels, provision is flaky enough by
        # itself.
        label_update_success = True
        start_time = datetime.datetime.now()
        try:
            host.update_labels()
        except Exception:
            logging.exception('Exception while updating labels.')
            label_update_success = False

        end_time = datetime.datetime.now()
        duration = (end_time - start_time).total_seconds()

        fields = {'success': label_update_success,
                  # TODO(kevcheng): Need a better way of classifying testbeds.
                  'board': (host.get_board()
                            if not utils.machine_is_testbed(machine)
                            else host.get_platform())}
        _LABEL_UPDATE_DURATION_METRIC.add(duration, fields=fields)
    except Exception:
        logging.exception('Provision failed due to Exception.')
        job.record('END FAIL', None, 'provision')
        # Raising a blank exception is done here because any message we can
        # give here would be less useful than whatever the failing test left as
        # its own exception message.
        #
        # The gory details of how raising a blank exception accomplishes this
        # is as follows:
        #
        # The scheduler only looks at the return code of autoserv to see if
        # the special task failed.  Therefore we need python to exit because
        # of an unhandled exception or because someone called sys.exit(1).
        #
        # We can't call sys.exit, since there's post-job-running logic (like
        # cleanup) that we'd be skipping out on.  So therefore, we need to
        # raise an exception.  However, if we raise an exception, this
        # exception ends up triggering server_job to write an INFO line with
        # job_abort_reason equal to str(e), which the tko parser then picks
        # up as the reason field for the job when the status.log we generate is
        # parsed as the job's results.
        #
        # So therefore, we raise a blank exception, which then generates an
        # empty job_abort_reason which the tko parser ignores just inserts as
        # a SERVER_JOB failure with no reason, which we then ignore at suite
        # results reporting time.
        raise Exception('')
    else:
        # If we finish successfully, nothing in autotest ever looks at the
        # status.log, so it's purely for human consumption and tracability.
        hostname = utils.get_hostname_from_machine(machine)
        job.record('END GOOD', None, 'provision',
                   '%s provisioned successfully' % hostname)


job.parallel_simple(provision_machine, machines)

# vim: set syntax=python :
