# Copyright 2017 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 standard functions for working with Autotest labels.

There are two types of labels, plain ("webcam") or keyval
("pool:suites").  Most of this module's functions work with keyval
labels.

Most users should use LabelsMapping, which provides a dict-like
interface for working with keyval labels.

This module also provides functions for working with cros version
strings, which are common keyval label values.
"""

import collections
import logging
import re

logger = logging.getLogger(__name__)


class Key(object):
    """Enum for keyval label keys."""
    CROS_VERSION = 'cros-version'
    ANDROID_BUILD_VERSION = 'ab-version'
    TESTBED_VERSION = 'testbed-version'
    FIRMWARE_RW_VERSION = 'fwrw-version'
    FIRMWARE_RO_VERSION = 'fwro-version'


class LabelsMapping(collections.MutableMapping):
    """dict-like interface for working with labels.

    The constructor takes an iterable of labels, either plain or keyval.
    Plain labels are saved internally and ignored except for converting
    back to string labels.  Keyval labels are exposed through a
    dict-like interface (pop(), keys(), items(), etc. are all
    supported).

    When multiple keyval labels share the same key, the first one wins.

    The one difference from a dict is that setting a key to None will
    delete the corresponding keyval label, since it does not make sense
    for a keyval label to have a None value.  Prefer using del or pop()
    instead of setting a key to None.

    LabelsMapping has one method getlabels() for converting back to
    string labels.
    """

    def __init__(self, str_labels):
        self._plain_labels = []
        self._keyval_map = collections.OrderedDict()
        for str_label in str_labels:
            self._add_label(str_label)

    def _add_label(self, str_label):
        """Add a label string to the internal map or plain labels list.

        If there is already a corresponding keyval in the internal map,
        skip adding the current label.  This is how existing labels code
        tends to handle it, but duplicate keys should be considered an
        anomaly.
        """
        try:
            keyval_label = parse_keyval_label(str_label)
        except ValueError:
            self._plain_labels.append(str_label)
        else:
            if keyval_label.key in self._keyval_map:
                logger.warning('Duplicate keyval label %r (current map %r)',
                               str_label, self._keyval_map)
            else:
                self._keyval_map[keyval_label.key] = keyval_label.value

    def __getitem__(self, key):
        return self._keyval_map[key]

    def __setitem__(self, key, val):
        if val is None:
            self.pop(key, None)
        else:
            self._keyval_map[key] = val

    def __delitem__(self, key):
        del self._keyval_map[key]

    def __iter__(self):
        return iter(self._keyval_map)

    def __len__(self):
        return len(self._keyval_map)

    def getlabels(self):
        """Return labels as a list of strings."""
        str_labels = self._plain_labels[:]
        keyval_labels = (KeyvalLabel(key, value)
                         for key, value in self.iteritems())
        str_labels.extend(format_keyval_label(label)
                          for label in keyval_labels)
        return str_labels


_KEYVAL_LABEL_SEP = ':'


KeyvalLabel = collections.namedtuple('KeyvalLabel', 'key, value')


def parse_keyval_label(str_label):
    """Parse a string as a KeyvalLabel.

    If the argument is not a valid keyval label, ValueError is raised.
    """
    key, value = str_label.split(_KEYVAL_LABEL_SEP, 1)
    return KeyvalLabel(key, value)


def format_keyval_label(keyval_label):
    """Format a KeyvalLabel as a string."""
    return _KEYVAL_LABEL_SEP.join(keyval_label)


CrosVersion = collections.namedtuple(
        'CrosVersion', 'group, milestone, version, rc')


_CROS_VERSION_REGEX = (
    r'^'
    r'(?P<group>[a-z0-9-]+)'
    r'/'
    r'(?P<milestone>R[0-9]+)'
    r'-'
    r'(?P<version>[0-9.]+)'
    r'(-(?P<rc>rc[0-9]+))?'
    r'$'
)


def parse_cros_version(version_string):
    """Parse a string as a CrosVersion.

    If the argument is not a valid cros version, ValueError is raised.
    Example cros version string: 'lumpy-release/R27-3773.0.0-rc1'
    """
    match = re.search(_CROS_VERSION_REGEX, version_string)
    if match is None:
        raise ValueError('Invalid cros version string: %r' % version_string)
    return CrosVersion(**match.groupdict())


def format_cros_version(cros_version):
    """Format a CrosVersion as a string."""
    if cros_version.rc is not None:
        return '{group}/{milestone}-{version}-{rc}'.format(
                **cros_version._asdict())
    else:
        return '{group}/{milestone}-{version}'.format(**cros_version._asdict())
