import logging
import os

from autotest_lib.client.common_lib import host_protections
from autotest_lib.server import crashcollect
from autotest_lib.server.cros import provision


# A string of the form 'label1,label2:value,label3'.
job_labels = locals().get('job_labels') or ','.join(args)
labels_list = [l.strip() for l in job_labels.split(',') if l]


def _call_repair(host):
    protection = host_protections.Protection

    try:
        level = protection.get_value(protection_level)
    except ValueError:
        raise NotImplementedError("Unknown host protection level %s" %
                                  protection_level)

    logging.debug('Protection level of host %s is %s: %s',
                  host.hostname, protection_level, level)
    host.repair_with_protection(level)


def repair(machine):
    try:
        job.record('START', None, 'repair')
        host = hosts.create_host(machine, initialize=False, auto_monitor=False,
                                 try_lab_servo=True)
        # Collect logs before the repair, as it might destroy all useful logs.
        local_log_dir = os.path.join(job.resultdir, machine, 'before_repair')
        host.collect_logs('/var/log', local_log_dir, ignore_errors=True)
        # Collect crash info.
        crashcollect.get_crashinfo(host, None)

        _call_repair(host)
        logging.debug('Repair with labels list %s', labels_list)
        provision.run_special_task_actions(job, host, labels_list,
                                           provision.Repair)
    except Exception as e:
        logging.exception(e)
        job.record('END FAIL', None, 'repair')
        # See the provision control segment for the explanation of why we're
        # doing this.
        raise Exception('')
    else:
        job.record('END GOOD', None, 'repair',
                   '%s repaired successfully' % machine)


job.parallel_simple(repair, machines)

# vim: set syntax=python :
