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

import common
from autotest_lib.frontend.afe.json_rpc import proxy
from autotest_lib.server import frontend


### Constants for label prefixes
CROS_VERSION_PREFIX = 'cros-version'
FW_VERSION_PREFIX = 'fw-version'


### Helpers to convert value to label
def cros_version_to_label(image):
    """
    Returns the proper label name for a ChromeOS build of |image|.

    @param image: A string of the form 'lumpy-release/R28-3993.0.0'
    @returns: A string that is the appropriate label name.

    """
    return CROS_VERSION_PREFIX + ':' + image


# TODO(milleral): http://crbug.com/249555
# Create some way to discover and register provisioning tests so that we don't
# need to hand-maintain a list of all of them.
_provision_types = {
    CROS_VERSION_PREFIX:'provision_AutoUpdate',
    FW_VERSION_PREFIX:'provision_FirmwareUpdate',
}


def can_provision(label):
    """
    Returns True if the label is a label that we recognize as something we
    know how to provision.

    @param label: The label as a string.
    @returns: True if there exists a test to provision the label.

    """
    return label.split(':')[0] in _provision_types


def provisioner_for(name):
    """
    Returns the provisioning class associated with the given (string) name.

    @param name: The name of the provision type being requested.
    @returns: The subclass of Provisioner that was requested.
    @raises KeyError: If the name was not recognized as a provision type.

    """
    return _provision_types[name]


def filter_labels(labels):
    """
    Filter a list of labels into two sets: those labels that we know how to
    change and those that we don't.  For the ones we know how to change, split
    them apart into the name of configuration type and its value.

    @param labels: A list of strings of labels.
    @returns: A tuple where the first element is a set of unprovisionable
              labels, and the second element is a set of the provisionable
              labels.

    >>> filter_labels(['bluetooth', 'cros-version:lumpy-release/R28-3993.0.0'])
    (set(['bluetooth']), set(['cros-version:lumpy-release/R28-3993.0.0']))

    """
    capabilities = set()
    configurations = set()

    for label in labels:
        if can_provision(label):
            configurations.add(label)
        else:
            capabilities.add(label)

    return capabilities, configurations


def split_labels(labels):
    """
    Split a list of labels into a dict mapping name to value.  All labels must
    be provisionable labels, or else a ValueError

    @param labels: list of strings of label names
    @returns: A dict of where the key is the configuration name, and the value
              is the configuration value.
    @raises: ValueError if a label is not a provisionable label.

    >>> split_labels(['cros-version:lumpy-release/R28-3993.0.0'])
    {'cros-version': 'lumpy-release/R28-3993.0.0'}
    >>> split_labels(['bluetooth'])
    Traceback (most recent call last):
    ...
    ValueError: Unprovisionable label bluetooth

    """
    configurations = dict()

    for label in labels:
        if can_provision(label):
            name, value = label.split(':', 1)
            configurations[name] = value
        else:
            raise ValueError('Unprovisionable label %s' % label)

    return configurations


def join(provision_type, provision_value):
    """
    Combine the provision type and value into the label name.

    @param provision_type: One of the constants that are the label prefixes.
    @param provision_value: A string of the value for this provision type.
    @returns: A string that is the label name for this (type, value) pair.

    >>> join(CROS_VERSION_PREFIX, 'lumpy-release/R27-3773.0.0')
    'cros-version:lumpy-release/R27-3773.0.0'

    """
    return '%s:%s' % (provision_type, provision_value)


# This has been copied out of dynamic_suite's reimager.py, which no longer
# exists.  I'd prefer if this would go away by doing http://crbug.com/249424,
# so that labels are just automatically made when we try to add them to a host.
def ensure_label_exists(name):
    """
    Ensure that a label called |name| exists in the autotest DB.

    @param name: the label to check for/create.
    @raises ValidationError: There was an error in the response that was
                             not because the label already existed.

    """
    afe = frontend.AFE()
    try:
        afe.create_label(name=name)
    except proxy.ValidationError as ve:
        if ('name' in ve.problem_keys and
            'This value must be unique' in ve.problem_keys['name']):
            logging.debug('Version label %s already exists', name)
        else:
            raise ve
