# Lint as: python2, python3
# 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.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import collections
import re
import six


class Key(object):
    """Enum for keyval label keys."""
    CROS_VERSION = 'cros-version'
    CROS_ANDROID_VERSION = 'cheets-version'
    FIRMWARE_RW_VERSION = 'fwrw-version'
    FIRMWARE_RO_VERSION = 'fwro-version'
    FIRMWARE_CR50_RW_VERSION = 'cr50-rw-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."""
        try:
            keyval_label = parse_keyval_label(str_label)
        except ValueError:
            self._plain_labels.append(str_label)
        else:
            if keyval_label.key not in self._keyval_map:
                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 six.iteritems(self))
        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())
