# 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'
    CROS_ANDROID_VERSION = 'cheets-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, board, 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'$'
)

_CROS_BOARD_FROM_VERSION_REGEX = (
        r'^'
        r'(trybot-)?'
        r'(?P<board>[a-z_-]+)-(release|paladin|pre-cq|test-ap|toolchain)'
        r'/R.*'
        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)
    parts = match.groupdict()
    match = re.search(_CROS_BOARD_FROM_VERSION_REGEX, version_string)
    if match is None:
        raise ValueError('Invalid cros version string: %r. Failed to parse '
                         'board.' % version_string)
    parts['board'] = match.group('board')
    return CrosVersion(**parts)


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())
