#
# Copyright 2008 Google Inc. All Rights Reserved.

"""
The acl module contains the objects and methods used to
manage ACLs in Autotest.

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

The common options are:
--alist / -A: file containing a list of ACLs

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

"""

import os, sys
from autotest_lib.cli import topic_common, action_common


class acl(topic_common.atest):
    """ACL class
    atest acl [create|delete|list|add|remove] <options>"""
    usage_action = '[create|delete|list|add|remove]'
    topic = 'acl_group'
    msg_topic = 'ACL'
    msg_items = '<acls>'

    def __init__(self):
        """Add to the parser the options common to all the ACL actions"""
        super(acl, self).__init__()
        self.parser.add_option('-A', '--alist',
                               help='File listing the ACLs',
                               type='string',
                               default=None,
                               metavar='ACL_FLIST')

        self.topic_parse_info = topic_common.item_parse_info(
            attribute_name='acls',
            filename_option='alist',
            use_leftover=True)


    def get_items(self):
        return self.acls


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


class acl_list(action_common.atest_list, acl):
    """atest acl list [--verbose]
    [--user <users>|--mach <machine>|--alist <file>] [<acls>]"""
    def __init__(self):
        super(acl_list, self).__init__()

        self.parser.add_option('-u', '--user',
                               help='List ACLs containing USER',
                               type='string',
                               metavar='USER')
        self.parser.add_option('-m', '--machine',
                               help='List ACLs containing MACHINE',
                               type='string',
                               metavar='MACHINE')


    def parse(self):
        user_info = topic_common.item_parse_info(attribute_name='users',
                                                 inline_option='user')
        host_info = topic_common.item_parse_info(attribute_name='hosts',
                                                 inline_option='machine')

        (options, leftover) = super(acl_list, self).parse([user_info,
                                                           host_info])

        users = getattr(self, 'users')
        hosts = getattr(self, 'hosts')
        acls = getattr(self, 'acls')
        if ((users and (hosts or acls)) or
            (hosts and acls)):
            self.invalid_syntax('Only specify one of --user,'
                                '--machine or ACL')

        if len(users) > 1:
            self.invalid_syntax('Only specify one <user>')
        if len(hosts) > 1:
            self.invalid_syntax('Only specify one <machine>')

        try:
            self.users = users[0]
        except IndexError:
            pass

        try:
            self.hosts = hosts[0]
        except IndexError:
            pass
        return (options, leftover)


    def execute(self):
        filters = {}
        check_results = {}
        if self.acls:
            filters['name__in'] = self.acls
            check_results['name__in'] = 'name'

        if self.users:
            filters['users__login'] = self.users
            check_results['users__login'] = None

        if self.hosts:
            filters['hosts__hostname'] = self.hosts
            check_results['hosts__hostname'] = None

        return super(acl_list,
                     self).execute(op='get_acl_groups',
                                   filters=filters,
                                   check_results=check_results)


    def output(self, results):
        # If an ACL was specified, always print its details
        if self.acls or self.verbose:
            sublist_keys=('hosts', 'users')
        else:
            sublist_keys=()

        super(acl_list, self).output(results,
                                     keys=('name', 'description'),
                                     sublist_keys=sublist_keys)


class acl_create(action_common.atest_create, acl):
    """atest acl create <acl> --desc <description>"""
    def __init__(self):
        super(acl_create, self).__init__()
        self.parser.add_option('-d', '--desc',
                               help='Creates the ACL with the DESCRIPTION',
                               type='string')
        self.parser.remove_option('--alist')


    def parse(self):
        (options, leftover) = super(acl_create, self).parse(req_items='acls')

        if not options.desc:
            self.invalid_syntax('Must specify a description to create an ACL.')

        self.data_item_key = 'name'
        self.data['description'] = options.desc

        if len(self.acls) > 1:
            self.invalid_syntax('Can only create one ACL at a time')

        return (options, leftover)


class acl_delete(action_common.atest_delete, acl):
    """atest acl delete [<acls> | --alist <file>"""
    pass


class acl_add_or_remove(acl):
    def __init__(self):
        super(acl_add_or_remove, self).__init__()
        # Get the appropriate help for adding or removing.
        words = self.usage_words
        lower_words = tuple(word.lower() for word in words)

        self.parser.add_option('-u', '--user',
                               help='%s USER(s) %s the ACL' % words,
                               type='string',
                               metavar='USER')
        self.parser.add_option('-U', '--ulist',
                               help='File containing users to %s %s '
                               'the ACL' % lower_words,
                               type='string',
                               metavar='USER_FLIST')
        self.parser.add_option('-m', '--machine',
                               help='%s MACHINE(s) %s the ACL' % words,
                               type='string',
                               metavar='MACHINE')
        self.parser.add_option('-M', '--mlist',
                               help='File containing machines to %s %s '
                               'the ACL' % lower_words,
                               type='string',
                               metavar='MACHINE_FLIST')


    def parse(self):
        user_info = topic_common.item_parse_info(attribute_name='users',
                                                 inline_option='user',
                                                 filename_option='ulist')
        host_info = topic_common.item_parse_info(attribute_name='hosts',
                                                 inline_option='machine',
                                                 filename_option='mlist')
        (options, leftover) = super(acl_add_or_remove,
                                    self).parse([user_info, host_info],
                                                req_items='acls')

        if (not getattr(self, 'users', None) and
            not getattr(self, 'hosts', None)):
            self.invalid_syntax('Specify at least one USER or MACHINE')

        return (options, leftover)


class acl_add(action_common.atest_add, acl_add_or_remove):
    """atest acl add <acl> --user <user>|
       --machine <machine>|--mlist <FILE>]"""
    pass


class acl_remove(action_common.atest_remove, acl_add_or_remove):
    """atest acl remove [<acls> | --alist <file>
    --user <user> | --machine <machine> | --mlist <FILE>]"""
    pass
