#
# 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 os, 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')


    def parse(self, flists=None, req_items='labels'):
        """Consume the common label options"""
        if flists:
            flists.append(('labels', 'blist', '', True))
        else:
            flists = [('labels', 'blist', '', True)]
        return self.parse_with_flist(flists, req_items)


    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):
        flists = [('hosts', '', 'machine', False)]
        (options, leftover) = super(label_list, self).parse(flists,
                                                            req_items=None)

        if options.all and options.platform_only:
            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()
        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):
    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):
        flists = [('hosts', 'mlist', 'machine', False)]
        (options, leftover) = super(label_add_or_remove, self).parse(flists)
        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
