# Lint as: python2, python3
# Copyright Martin J. Bligh Google LLC 2008
# Released under the GPL v2

"""
This class allows you to communicate with the frontend to submit jobs etc
It is designed for writing more sophisiticated server-side control files that
can recursively add and manage other jobs.

We turn the JSON dictionaries into real objects that are more idiomatic

For docs, see:
    http://www.chromium.org/chromium-os/testing/afe-rpc-infrastructure
    http://docs.djangoproject.com/en/dev/ref/models/querysets/#queryset-api
"""

#pylint: disable=missing-docstring

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import getpass
import os
import re

import common

from autotest_lib.frontend.afe import rpc_client_lib
from autotest_lib.client.common_lib import control_data
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import host_states
from autotest_lib.client.common_lib import priorities
from autotest_lib.client.common_lib import utils
from autotest_lib.tko import db
from six.moves import zip

try:
    from autotest_lib.utils.frozen_chromite.lib import metrics
except ImportError:
    metrics = utils.metrics_mock

try:
    from autotest_lib.server.site_common import site_utils as server_utils
except:
    from autotest_lib.server import utils as server_utils
form_ntuples_from_machines = server_utils.form_ntuples_from_machines

GLOBAL_CONFIG = global_config.global_config
DEFAULT_SERVER = 'autotest'


def dump_object(header, obj):
    """
    Standard way to print out the frontend objects (eg job, host, acl, label)
    in a human-readable fashion for debugging
    """
    result = header + '\n'
    for key in obj.hash:
        if key == 'afe' or key == 'hash':
            continue
        result += '%20s: %s\n' % (key, obj.hash[key])
    return result


class RpcClient(object):
    """
    Abstract RPC class for communicating with the autotest frontend
    Inherited for both TKO and AFE uses.

    All the constructors go in the afe / tko class.
    Manipulating methods go in the object classes themselves
    """
    def __init__(self, path, user, server, print_log, debug, reply_debug):
        """
        Create a cached instance of a connection to the frontend

            user: username to connect as
            server: frontend server to connect to
            print_log: pring a logging message to stdout on every operation
            debug: print out all RPC traffic
        """
        if not user and utils.is_in_container():
            user = GLOBAL_CONFIG.get_config_value('SSP', 'user', default=None)
        if not user:
            user = getpass.getuser()
        if not server:
            if 'AUTOTEST_WEB' in os.environ:
                server = os.environ['AUTOTEST_WEB']
            else:
                server = GLOBAL_CONFIG.get_config_value('SERVER', 'hostname',
                                                        default=DEFAULT_SERVER)
        self.server = server
        self.user = user
        self.print_log = print_log
        self.debug = debug
        self.reply_debug = reply_debug
        headers = {'AUTHORIZATION': self.user}
        rpc_server = rpc_client_lib.add_protocol(server) + path
        if debug:
            print('SERVER: %s' % rpc_server)
            print('HEADERS: %s' % headers)
        self.proxy = rpc_client_lib.get_proxy(rpc_server, headers=headers)


    def run(self, call, **dargs):
        """
        Make a RPC call to the AFE server
        """
        rpc_call = getattr(self.proxy, call)
        if self.debug:
            print('DEBUG: %s %s' % (call, dargs))
        try:
            result = utils.strip_unicode(rpc_call(**dargs))
            if self.reply_debug:
                print(result)
            return result
        except Exception:
            raise


    def log(self, message):
        if self.print_log:
            print(message)


class TKO(RpcClient):
    def __init__(self, user=None, server=None, print_log=True, debug=False,
                 reply_debug=False):
        super(TKO, self).__init__(path='/new_tko/server/noauth/rpc/',
                                  user=user,
                                  server=server,
                                  print_log=print_log,
                                  debug=debug,
                                  reply_debug=reply_debug)
        self._db = None


    @metrics.SecondsTimerDecorator(
            'chromeos/autotest/tko/get_job_status_duration')
    def get_job_test_statuses_from_db(self, job_id):
        """Get job test statuses from the database.

        Retrieve a set of fields from a job that reflect the status of each test
        run within a job.
        fields retrieved: status, test_name, reason, test_started_time,
                          test_finished_time, afe_job_id, job_owner, hostname.

        @param job_id: The afe job id to look up.
        @returns a TestStatus object of the resulting information.
        """
        if self._db is None:
            self._db = db.db()
        fields = ['status', 'test_name', 'subdir', 'reason',
                  'test_started_time', 'test_finished_time', 'afe_job_id',
                  'job_owner', 'hostname', 'job_tag']
        table = 'tko_test_view_2'
        where = 'job_tag like "%s-%%"' % job_id
        test_status = []
        # Run commit before we query to ensure that we are pulling the latest
        # results.
        self._db.commit()
        for entry in self._db.select(','.join(fields), table, (where, None)):
            status_dict = {}
            for key,value in zip(fields, entry):
                # All callers expect values to be a str object.
                status_dict[key] = str(value)
            # id is used by TestStatus to uniquely identify each Test Status
            # obj.
            status_dict['id'] = [status_dict['reason'], status_dict['hostname'],
                                 status_dict['test_name']]
            test_status.append(status_dict)

        return [TestStatus(self, e) for e in test_status]


    def get_status_counts(self, job, **data):
        entries = self.run('get_status_counts',
                           group_by=['hostname', 'test_name', 'reason'],
                           job_tag__startswith='%s-' % job, **data)
        return [TestStatus(self, e) for e in entries['groups']]


class _StableVersionMap(object):
    """
    A mapping from board names to strings naming software versions.

    The mapping is meant to allow finding a nominally "stable" version
    of software associated with a given board.  The mapping identifies
    specific versions of software that should be installed during
    operations such as repair.

    Conceptually, there are multiple version maps, each handling
    different types of image.  For instance, a single board may have
    both a stable OS image (e.g. for CrOS), and a separate stable
    firmware image.

    Each different type of image requires a certain amount of special
    handling, implemented by a subclass of `StableVersionMap`.  The
    subclasses take care of pre-processing of arguments, delegating
    actual RPC calls to this superclass.

    @property _afe      AFE object through which to make the actual RPC
                        calls.
    @property _android  Value of the `android` parameter to be passed
                        when calling the `get_stable_version` RPC.
    """

    def __init__(self, afe):
        self._afe = afe


    def get_all_versions(self):
        """
        Get all mappings in the stable versions table.

        Extracts the full content of the `stable_version` table
        in the AFE database, and returns it as a dictionary
        mapping board names to version strings.

        @return A dictionary mapping board names to version strings.
        """
        return self._afe.run('get_all_stable_versions')


    def get_version(self, board):
        """
        Get the mapping of one board in the stable versions table.

        Look up and return the version mapped to the given board in the
        `stable_versions` table in the AFE database.

        @param board  The board to be looked up.

        @return The version mapped for the given board.
        """
        return self._afe.run('get_stable_version', board=board)


    def set_version(self, board, version):
        """
        Change the mapping of one board in the stable versions table.

        Set the mapping in the `stable_versions` table in the AFE
        database for the given board to the given version.

        @param board    The board to be updated.
        @param version  The new version to be assigned to the board.
        """
        raise RuntimeError("server.frontend._StableVersionMap::set_version is intentionally deleted")


    def delete_version(self, board):
        """
        Remove the mapping of one board in the stable versions table.

        Remove the mapping in the `stable_versions` table in the AFE
        database for the given board.

        @param board    The board to be updated.
        """
        raise RuntimeError("server.frontend._StableVersionMap::delete_version is intentionally deleted")


class _OSVersionMap(_StableVersionMap):
    """
    Abstract stable version mapping for full OS images of various types.
    """

    def _version_is_valid(self, version):
        return True

    def get_all_versions(self):
        versions = super(_OSVersionMap, self).get_all_versions()
        for board in versions.keys():
            if ('/' in board
                    or not self._version_is_valid(versions[board])):
                del versions[board]
        return versions

    def get_version(self, board):
        version = super(_OSVersionMap, self).get_version(board)
        return version if self._version_is_valid(version) else None


def format_cros_image_name(board, version):
    """
    Return an image name for a given `board` and `version`.

    This formats `board` and `version` into a string identifying an
    image file.  The string represents part of a URL for access to
    the image.

    The returned image name is typically of a form like
    "falco-release/R55-8872.44.0".
    """
    build_pattern = GLOBAL_CONFIG.get_config_value(
            'CROS', 'stable_build_pattern')
    return build_pattern % (board, version)


class _CrosVersionMap(_OSVersionMap):
    """
    Stable version mapping for ChromeOS release images.

    This class manages a mapping of ChromeOS board names to known-good
    release (or canary) images.  The images selected can be installed on
    DUTs during repair tasks, as a way of getting a DUT into a known
    working state.
    """

    def _version_is_valid(self, version):
        return version is not None and '/' not in version

    def get_image_name(self, board):
        """
        Return the full image name of the stable version for `board`.

        This finds the stable version for `board`, and returns a string
        identifying the associated image as for `format_image_name()`,
        above.

        @return A string identifying the image file for the stable
                image for `board`.
        """
        return format_cros_image_name(board, self.get_version(board))


class _SuffixHackVersionMap(_StableVersionMap):
    """
    Abstract super class for mappings using a pseudo-board name.

    For non-OS image type mappings, we look them up in the
    `stable_versions` table by constructing a "pseudo-board" from the
    real board name plus a suffix string that identifies the image type.
    So, for instance the name "lulu/firmware" is used to look up the
    FAFT firmware version for lulu boards.
    """

    # _SUFFIX - The suffix used in constructing the "pseudo-board"
    # lookup key.  Each subclass must define this value for itself.
    #
    _SUFFIX = None

    def get_all_versions(self):
        # Get all the mappings from the AFE, extract just the mappings
        # with our suffix, and replace the pseudo-board name keys with
        # the real board names.
        #
        all_versions = super(
                _SuffixHackVersionMap, self).get_all_versions()
        return {
            board[0 : -len(self._SUFFIX)]: all_versions[board]
                for board in all_versions.keys()
                    if board.endswith(self._SUFFIX)
        }


    def get_version(self, board):
        board += self._SUFFIX
        return super(_SuffixHackVersionMap, self).get_version(board)


    def set_version(self, board, version):
        board += self._SUFFIX
        super(_SuffixHackVersionMap, self).set_version(board, version)


    def delete_version(self, board):
        board += self._SUFFIX
        super(_SuffixHackVersionMap, self).delete_version(board)


class _FAFTVersionMap(_SuffixHackVersionMap):
    """
    Stable version mapping for firmware versions used in FAFT repair.

    When DUTs used for FAFT fail repair, stable firmware may need to be
    flashed directly from original tarballs.  The FAFT firmware version
    mapping finds the appropriate tarball for a given board.
    """

    _SUFFIX = '/firmware'

    def get_version(self, board):
        # If there's no mapping for `board`, the lookup will return the
        # default CrOS version mapping.  To eliminate that case, we
        # require a '/' character in the version, since CrOS versions
        # won't match that.
        #
        # TODO(jrbarnette):  This is, of course, a hack.  Ultimately,
        # the right fix is to move handling to the RPC server side.
        #
        version = super(_FAFTVersionMap, self).get_version(board)
        return version if '/' in version else None


class _FirmwareVersionMap(_SuffixHackVersionMap):
    """
    Stable version mapping for firmware supplied in ChromeOS images.

    A ChromeOS image bundles a version of the firmware that the
    device should update to when the OS version is installed during
    AU.

    Test images suppress the firmware update during AU.  Instead, during
    repair and verify we check installed firmware on a DUT, compare it
    against the stable version mapping for the board, and update when
    the DUT is out-of-date.
    """

    _SUFFIX = '/rwfw'

    def get_version(self, board):
        # If there's no mapping for `board`, the lookup will return the
        # default CrOS version mapping.  To eliminate that case, we
        # require the version start with "Google_", since CrOS versions
        # won't match that.
        #
        # TODO(jrbarnette):  This is, of course, a hack.  Ultimately,
        # the right fix is to move handling to the RPC server side.
        #
        version = super(_FirmwareVersionMap, self).get_version(board)
        return version if version.startswith('Google_') else None


class AFE(RpcClient):

    # Known image types for stable version mapping objects.
    # CROS_IMAGE_TYPE - Mappings for ChromeOS images.
    # FAFT_IMAGE_TYPE - Mappings for Firmware images for FAFT repair.
    # FIRMWARE_IMAGE_TYPE - Mappings for released RW Firmware images.
    #
    CROS_IMAGE_TYPE = 'cros'
    FAFT_IMAGE_TYPE = 'faft'
    FIRMWARE_IMAGE_TYPE = 'firmware'

    _IMAGE_MAPPING_CLASSES = {
        CROS_IMAGE_TYPE: _CrosVersionMap,
        FAFT_IMAGE_TYPE: _FAFTVersionMap,
        FIRMWARE_IMAGE_TYPE: _FirmwareVersionMap,
    }


    def __init__(self, user=None, server=None, print_log=True, debug=False,
                 reply_debug=False, job=None):
        self.job = job
        super(AFE, self).__init__(path='/afe/server/noauth/rpc/',
                                  user=user,
                                  server=server,
                                  print_log=print_log,
                                  debug=debug,
                                  reply_debug=reply_debug)


    def get_stable_version_map(self, image_type):
        """
        Return a stable version mapping for the given image type.

        @return An object mapping board names to version strings for
                software of the given image type.
        """
        return self._IMAGE_MAPPING_CLASSES[image_type](self)


    def host_statuses(self, live=None):
        dead_statuses = ['Repair Failed', 'Repairing']
        statuses = self.run('get_static_data')['host_statuses']
        if live == True:
            return list(set(statuses) - set(dead_statuses))
        if live == False:
            return dead_statuses
        else:
            return statuses


    @staticmethod
    def _dict_for_host_query(hostnames=(), status=None, label=None):
        query_args = {}
        if hostnames:
            query_args['hostname__in'] = hostnames
        if status:
            query_args['status'] = status
        if label:
            query_args['labels__name'] = label
        return query_args


    def get_hosts(self, hostnames=(), status=None, label=None, **dargs):
        query_args = dict(dargs)
        query_args.update(self._dict_for_host_query(hostnames=hostnames,
                                                    status=status,
                                                    label=label))
        hosts = self.run('get_hosts', **query_args)
        return [Host(self, h) for h in hosts]


    def get_hostnames(self, status=None, label=None, **dargs):
        """Like get_hosts() but returns hostnames instead of Host objects."""
        # This implementation can be replaced with a more efficient one
        # that does not query for entire host objects in the future.
        return [host_obj.hostname for host_obj in
                self.get_hosts(status=status, label=label, **dargs)]


    def reverify_hosts(self, hostnames=(), status=None, label=None):
        query_args = dict(locked=False,
                          aclgroup__users__login=self.user)
        query_args.update(self._dict_for_host_query(hostnames=hostnames,
                                                    status=status,
                                                    label=label))
        return self.run('reverify_hosts', **query_args)


    def repair_hosts(self, hostnames=(), status=None, label=None):
        query_args = dict(locked=False,
                          aclgroup__users__login=self.user)
        query_args.update(self._dict_for_host_query(hostnames=hostnames,
                                                    status=status,
                                                    label=label))
        return self.run('repair_hosts', **query_args)


    def create_host(self, hostname, **dargs):
        id = self.run('add_host', hostname=hostname, **dargs)
        return self.get_hosts(id=id)[0]


    def get_host_attribute(self, attr, **dargs):
        host_attrs = self.run('get_host_attribute', attribute=attr, **dargs)
        return [HostAttribute(self, a) for a in host_attrs]


    def set_host_attribute(self, attr, val, **dargs):
        self.run('set_host_attribute', attribute=attr, value=val, **dargs)


    def get_labels(self, **dargs):
        labels = self.run('get_labels', **dargs)
        return [Label(self, l) for l in labels]


    def create_label(self, name, **dargs):
        id = self.run('add_label', name=name, **dargs)
        return self.get_labels(id=id)[0]


    def get_acls(self, **dargs):
        acls = self.run('get_acl_groups', **dargs)
        return [Acl(self, a) for a in acls]


    def create_acl(self, name, **dargs):
        id = self.run('add_acl_group', name=name, **dargs)
        return self.get_acls(id=id)[0]


    def get_users(self, **dargs):
        users = self.run('get_users', **dargs)
        return [User(self, u) for u in users]


    def generate_control_file(self, tests, **dargs):
        ret = self.run('generate_control_file', tests=tests, **dargs)
        return ControlFile(self, ret)


    def get_jobs(self, summary=False, **dargs):
        if summary:
            jobs_data = self.run('get_jobs_summary', **dargs)
        else:
            jobs_data = self.run('get_jobs', **dargs)
        jobs = []
        for j in jobs_data:
            job = Job(self, j)
            # Set up some extra information defaults
            job.testname = re.sub('\s.*', '', job.name) # arbitrary default
            job.platform_results = {}
            job.platform_reasons = {}
            jobs.append(job)
        return jobs


    def get_host_queue_entries(self, **kwargs):
        """Find JobStatus objects matching some constraints.

        @param **kwargs: Arguments to pass to the RPC
        """
        entries = self.run('get_host_queue_entries', **kwargs)
        return self._entries_to_statuses(entries)


    def get_host_queue_entries_by_insert_time(self, **kwargs):
        """Like get_host_queue_entries, but using the insert index table.

        @param **kwargs: Arguments to pass to the RPC
        """
        entries = self.run('get_host_queue_entries_by_insert_time', **kwargs)
        return self._entries_to_statuses(entries)


    def _entries_to_statuses(self, entries):
        """Converts HQEs to JobStatuses

        Sadly, get_host_queue_entries doesn't return platforms, we have
        to get those back from an explicit get_hosts queury, then patch
        the new host objects back into the host list.

        :param entries: A list of HQEs from get_host_queue_entries or
          get_host_queue_entries_by_insert_time.
        """
        job_statuses = [JobStatus(self, e) for e in entries]
        hostnames = [s.host.hostname for s in job_statuses if s.host]
        hosts = {}
        for host in self.get_hosts(hostname__in=hostnames):
            hosts[host.hostname] = host
        for status in job_statuses:
            if status.host:
                status.host = hosts.get(status.host.hostname)
        # filter job statuses that have either host or meta_host
        return [status for status in job_statuses if (status.host or
                                                      status.meta_host)]


    def get_special_tasks(self, **data):
        tasks = self.run('get_special_tasks', **data)
        return [SpecialTask(self, t) for t in tasks]


    def get_host_special_tasks(self, host_id, **data):
        tasks = self.run('get_host_special_tasks',
                         host_id=host_id, **data)
        return [SpecialTask(self, t) for t in tasks]


    def get_host_status_task(self, host_id, end_time):
        task = self.run('get_host_status_task',
                        host_id=host_id, end_time=end_time)
        return SpecialTask(self, task) if task else None


    def get_host_diagnosis_interval(self, host_id, end_time, success):
        return self.run('get_host_diagnosis_interval',
                        host_id=host_id, end_time=end_time,
                        success=success)


    def create_job(self, control_file, name=' ',
                   priority=priorities.Priority.DEFAULT,
                   control_type=control_data.CONTROL_TYPE_NAMES.CLIENT,
                   **dargs):
        id = self.run('create_job', name=name, priority=priority,
                 control_file=control_file, control_type=control_type, **dargs)
        return self.get_jobs(id=id)[0]


    def abort_jobs(self, jobs):
        """Abort a list of jobs.

        Already completed jobs will not be affected.

        @param jobs: List of job ids to abort.
        """
        for job in jobs:
            self.run('abort_host_queue_entries', job_id=job)


    def get_hosts_by_attribute(self, attribute, value):
        """
        Get the list of hosts that share the same host attribute value.

        @param attribute: String of the host attribute to check.
        @param value: String of the value that is shared between hosts.

        @returns List of hostnames that all have the same host attribute and
                 value.
        """
        return self.run('get_hosts_by_attribute',
                        attribute=attribute, value=value)


    def lock_host(self, host, lock_reason, fail_if_locked=False):
        """
        Lock the given host with the given lock reason.

        Locking a host that's already locked using the 'modify_hosts' rpc
        will raise an exception. That's why fail_if_locked exists so the
        caller can determine if the lock succeeded or failed.  This will
        save every caller from wrapping lock_host in a try-except.

        @param host: hostname of host to lock.
        @param lock_reason: Reason for locking host.
        @param fail_if_locked: Return False if host is already locked.

        @returns Boolean, True if lock was successful, False otherwise.
        """
        try:
            self.run('modify_hosts',
                     host_filter_data={'hostname': host},
                     update_data={'locked': True,
                                  'lock_reason': lock_reason})
        except Exception:
            return not fail_if_locked
        return True


    def unlock_hosts(self, locked_hosts):
        """
        Unlock the hosts.

        Unlocking a host that's already unlocked will do nothing so we don't
        need any special try-except clause here.

        @param locked_hosts: List of hostnames of hosts to unlock.
        """
        self.run('modify_hosts',
                 host_filter_data={'hostname__in': locked_hosts},
                 update_data={'locked': False,
                              'lock_reason': ''})


class TestResults(object):
    """
    Container class used to hold the results of the tests for a job
    """
    def __init__(self):
        self.good = []
        self.fail = []
        self.pending = []


    def add(self, result):
        if result.complete_count > result.pass_count:
            self.fail.append(result)
        elif result.incomplete_count > 0:
            self.pending.append(result)
        else:
            self.good.append(result)


class RpcObject(object):
    """
    Generic object used to construct python objects from rpc calls
    """
    def __init__(self, afe, hash):
        self.afe = afe
        self.hash = hash
        self.__dict__.update(hash)


    def __str__(self):
        return dump_object(self.__repr__(), self)


class ControlFile(RpcObject):
    """
    AFE control file object

    Fields: synch_count, dependencies, control_file, is_server
    """
    def __repr__(self):
        return 'CONTROL FILE: %s' % self.control_file


class Label(RpcObject):
    """
    AFE label object

    Fields:
        name, invalid, platform, kernel_config, id, only_if_needed
    """
    def __repr__(self):
        return 'LABEL: %s' % self.name


    def add_hosts(self, hosts):
        # We must use the label's name instead of the id because label ids are
        # not consistent across main-shard.
        return self.afe.run('label_add_hosts', id=self.name, hosts=hosts)


    def remove_hosts(self, hosts):
        # We must use the label's name instead of the id because label ids are
        # not consistent across main-shard.
        return self.afe.run('label_remove_hosts', id=self.name, hosts=hosts)


class Acl(RpcObject):
    """
    AFE acl object

    Fields:
        users, hosts, description, name, id
    """
    def __repr__(self):
        return 'ACL: %s' % self.name


    def add_hosts(self, hosts):
        self.afe.log('Adding hosts %s to ACL %s' % (hosts, self.name))
        return self.afe.run('acl_group_add_hosts', self.id, hosts)


    def remove_hosts(self, hosts):
        self.afe.log('Removing hosts %s from ACL %s' % (hosts, self.name))
        return self.afe.run('acl_group_remove_hosts', self.id, hosts)


    def add_users(self, users):
        self.afe.log('Adding users %s to ACL %s' % (users, self.name))
        return self.afe.run('acl_group_add_users', id=self.name, users=users)


class Job(RpcObject):
    """
    AFE job object

    Fields:
        name, control_file, control_type, synch_count, reboot_before,
        run_verify, priority, email_list, created_on, dependencies,
        timeout, owner, reboot_after, id
    """
    def __repr__(self):
        return 'JOB: %s' % self.id


class JobStatus(RpcObject):
    """
    AFE job_status object

    Fields:
        status, complete, deleted, meta_host, host, active, execution_subdir, id
    """
    def __init__(self, afe, hash):
        super(JobStatus, self).__init__(afe, hash)
        self.job = Job(afe, self.job)
        if getattr(self, 'host'):
            self.host = Host(afe, self.host)


    def __repr__(self):
        if self.host and self.host.hostname:
            hostname = self.host.hostname
        else:
            hostname = 'None'
        return 'JOB STATUS: %s-%s' % (self.job.id, hostname)


class SpecialTask(RpcObject):
    """
    AFE special task object
    """
    def __init__(self, afe, hash):
        super(SpecialTask, self).__init__(afe, hash)
        self.host = Host(afe, self.host)


    def __repr__(self):
        return 'SPECIAL TASK: %s' % self.id


class Host(RpcObject):
    """
    AFE host object

    Fields:
        status, lock_time, locked_by, locked, hostname, invalid,
        labels, platform, protection, dirty, id
    """
    def __repr__(self):
        return 'HOST OBJECT: %s' % self.hostname


    def show(self):
        labels = list(set(self.labels) - set([self.platform]))
        print('%-6s %-7s %-7s %-16s %s' % (self.hostname, self.status,
                                           self.locked, self.platform,
                                           ', '.join(labels)))


    def delete(self):
        return self.afe.run('delete_host', id=self.id)


    def modify(self, **dargs):
        return self.afe.run('modify_host', id=self.id, **dargs)


    def get_acls(self):
        return self.afe.get_acls(hosts__hostname=self.hostname)


    def add_acl(self, acl_name):
        self.afe.log('Adding ACL %s to host %s' % (acl_name, self.hostname))
        return self.afe.run('acl_group_add_hosts', id=acl_name,
                            hosts=[self.hostname])


    def remove_acl(self, acl_name):
        self.afe.log('Removing ACL %s from host %s' % (acl_name, self.hostname))
        return self.afe.run('acl_group_remove_hosts', id=acl_name,
                            hosts=[self.hostname])


    def get_labels(self):
        return self.afe.get_labels(host__hostname__in=[self.hostname])


    def add_labels(self, labels):
        self.afe.log('Adding labels %s to host %s' % (labels, self.hostname))
        return self.afe.run('host_add_labels', id=self.id, labels=labels)


    def remove_labels(self, labels):
        self.afe.log('Removing labels %s from host %s' % (labels,self.hostname))
        return self.afe.run('host_remove_labels', id=self.id, labels=labels)


    def is_available(self):
        """Check whether DUT host is available.

        @return: bool
        """
        return not (self.locked
                    or self.status in host_states.UNAVAILABLE_STATES)


class User(RpcObject):
    def __repr__(self):
        return 'USER: %s' % self.login


class TestStatus(RpcObject):
    """
    TKO test status object

    Fields:
        test_idx, hostname, testname, id
        complete_count, incomplete_count, group_count, pass_count
    """
    def __repr__(self):
        return 'TEST STATUS: %s' % self.id


class HostAttribute(RpcObject):
    """
    AFE host attribute object

    Fields:
        id, host, attribute, value
    """
    def __repr__(self):
        return 'HOST ATTRIBUTE %d' % self.id
