#
# Copyright 2008 Google Inc. All Rights Reserved.

"""
The label module contains the objects and methods used to
manage labels in Autotest.

The valid actions are:
add:     adds label(s), or hosts to an LABEL
remove:      deletes label(s), or hosts from an LABEL
list:    lists label(s)

The common options are:
--blist / -B: file containing a list of LABELs

See topic_common.py for a High Level Design and Algorithm.
"""

import sys
from autotest_lib.cli import topic_common, action_common


class label(topic_common.atest):
    """Label class
    atest label [create|delete|list|add|remove] <options>"""
    usage_action = '[create|delete|list|add|remove]'
    topic = msg_topic = 'label'
    msg_items = '<labels>'

    def __init__(self):
        """Add to the parser the options common to all the
        label actions"""
        super(label, self).__init__()

        self.parser.add_option('-B', '--blist',
                               help='File listing the labels',
                               type='string',
                               default=None,
                               metavar='LABEL_FLIST')

        self.topic_parse_info = topic_common.item_parse_info(
            attribute_name='labels',
            filename_option='blist',
            use_leftover=True)


    def get_items(self):
        return self.labels


class label_help(label):
    """Just here to get the atest logic working.
    Usage is set by its parent"""
    pass


class label_list(action_common.atest_list, label):
    """atest label list [--platform] [--all]
    [--valid-only] [--machine <machine>]
    [--blist <file>] [<labels>]"""
    def __init__(self):
        super(label_list, self).__init__()

        self.parser.add_option('-t', '--platform-only',
                               help='Display only platform labels',
                               action='store_true')

        self.parser.add_option('-d', '--valid-only',
                               help='Display only valid labels',
                               action='store_true')

        self.parser.add_option('-a', '--all',
                               help=('Display both normal & '
                                     'platform labels'),
                               action='store_true')

        self.parser.add_option('-m', '--machine',
                               help='List LABELs of MACHINE',
                               type='string',
                               metavar='MACHINE')


    def parse(self):
        host_info = topic_common.item_parse_info(attribute_name='hosts',
                                                 inline_option='machine')
        (options, leftover) = super(label_list, self).parse([host_info])

        exclusives = [options.all, options.platform_only]
        if exclusives.count(True) > 1:
            self.invalid_syntax('Only specify one of --all,'
                                '--platform')

        if len(self.hosts) > 1:
            self.invalid_syntax(('Only one machine name allowed. '
                                '''Use '%s host list %s' '''
                                 'instead.') %
                                (sys.argv[0], ','.join(self.hosts)))
        self.all = options.all
        self.platform_only = options.platform_only
        self.valid_only = options.valid_only
        return (options, leftover)


    def execute(self):
        filters = {}
        check_results = {}
        if self.hosts:
            filters['host__hostname__in'] = self.hosts
            check_results['host__hostname__in'] = None

        if self.labels:
            filters['name__in'] = self.labels
            check_results['name__in'] = 'name'

        return super(label_list, self).execute(op='get_labels',
                                               filters=filters,
                                               check_results=check_results)


    def output(self, results):
        if self.valid_only:
            results = [label for label in results
                       if not label['invalid']]

        if self.platform_only:
            results = [label for label in results
                       if label['platform']]
            keys = ['name', 'invalid']
        elif not self.all:
            results = [label for label in results
                       if not label['platform']]
            keys = ['name', 'only_if_needed', 'invalid']
        else:
            keys = ['name', 'platform', 'only_if_needed', 'invalid']

        super(label_list, self).output(results, keys)


class label_create(action_common.atest_create, label):
    """atest label create <labels>|--blist <file> --platform"""
    def __init__(self):
        super(label_create, self).__init__()
        self.parser.add_option('-t', '--platform',
                               help='To create this label as a platform',
                               default=False,
                               action='store_true')
        self.parser.add_option('-o', '--only_if_needed',
                               help='To mark the label as "only use if needed',
                               default=False,
                               action='store_true')


    def parse(self):
        (options, leftover) = super(label_create,
                                    self).parse(req_items='labels')
        self.data_item_key = 'name'
        self.data['platform'] = options.platform
        self.data['only_if_needed'] = options.only_if_needed
        return (options, leftover)


class label_delete(action_common.atest_delete, label):
    """atest label delete <labels>|--blist <file>"""
    pass



class label_add_or_remove(label):
    """Parent for `atest label` add and `label remove`"""
    def __init__(self):
        super(label_add_or_remove, self).__init__()
        lower_words = tuple(word.lower() for word in self.usage_words)
        self.parser.add_option('-m', '--machine',
                               help=('%s MACHINE(s) %s the LABEL' %
                                     self.usage_words),
                               type='string',
                               metavar='MACHINE')
        self.parser.add_option('-M', '--mlist',
                               help='File containing machines to %s %s '
                               'the LABEL' % lower_words,
                               type='string',
                               metavar='MACHINE_FLIST')


    def parse(self):
        host_info = topic_common.item_parse_info(attribute_name='hosts',
                                                 inline_option='machine',
                                                 filename_option='mlist')
        (options, leftover) = super(label_add_or_remove,
                                    self).parse([host_info],
                                                req_items='labels')

        if not getattr(self, 'hosts', None):
            self.invalid_syntax('%s %s requires at least one host' %
                                (self.msg_topic,
                                 self.usage_action))
        return (options, leftover)


class label_add(action_common.atest_add, label_add_or_remove):
    """atest label add <labels>|--blist <file>
    --platform [--machine <machine>] [--mlist <file>]"""
    pass


class label_remove(action_common.atest_remove, label_add_or_remove):
    """atest label remove <labels>|--blist <file>
     [--machine <machine>] [--mlist <file>]"""
    pass
