# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Yet another domain specific client for Swarming."""

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

import json
import os
import urllib

from lucifer import autotest
from skylab_staging import errors

# This is hard-coded everywhere -- on builders requesting skylab suite as well
# as in commands to be generated by users requesting one off suites.
_SKYLAB_RUN_SUITE_PATH = '/usr/local/autotest/bin/run_suite_skylab'
_SWARMING_POOL_SKYLAB_BOTS = 'ChromeOSSkylab'
_SWARMING_POOL_SKYLAB_SUITE_BOTS = 'ChromeOSSkylab-suite'
# Test push creates all suites at the highest allowed non-admin task priority.
# This ensures that test push tasks are prioritized over any user created tasks
# in the staging lab.
_TEST_PUSH_SUITE_PRIORITY = 50



class Client(object):
  """A domain specific client for Swarming service."""

  def __init__(self, cli_path, host, service_account_json=None):
    self._cli_path = cli_path
    self._host = host
    self._service_account_json = service_account_json

  def num_ready_duts(self, board, pool):
    """Count the number of DUTs in the given board, pool in dut_state ready.

    @param board: The board autotest label of the DUTs.
    @param pool: The pool autotest label of the DUTs.
    @returns number of DUTs in dut_state ready.
    """
    qargs = [
        ('dimensions', 'pool:%s' % _SWARMING_POOL_SKYLAB_BOTS),
        ('dimensions', 'label-board:%s' % board),
        ('dimensions', 'label-pool:%s' % pool),
        ('dimensions', 'dut_state:ready'),
    ]
    result = self.query('bots/count', qargs)
    if not result:
      return 0
    return int(result['count']) - (int(result['busy'])
                                   + int(result['dead'])
                                   + int(result['quarantined'])
                                   + int(result['maintenance']))

  def query(self, path, qargs):
    """Run a Swarming 'query' call.

    @param path: Path of the query RPC call.
    @qargs: Arguments for the RPC call.
    @returns: json response from the Swarming call.
    """
    cros_build_lib = autotest.chromite_load('cros_build_lib')
    cmd = self._base_cmd('query') + [
        '%s?%s' % (path, urllib.urlencode(qargs)),
    ]
    result = cros_build_lib.RunCommand(cmd, capture_output=True)
    return json.loads(result.output)

  def trigger_suite(self, board, pool, build, suite_name, timeout_s):
    """Trigger an autotest suite. Use wait_for_suite to wait for results.

    @param board: The board autotest label of the DUTs.
    @param pool: The pool autotest label of the DUTs.
    @param build: The build to test, e.g. link-paladin/R70-10915.0.0-rc1.
    @param suite_name: The name of the suite to run, e.g. provision.
    @param timeout_s: Timeout for the suite, in seconds.
    @returns: The task ID of the kicked off suite.
    """
    raw_cmd = self._suite_cmd_common(board, pool, build, suite_name, timeout_s)
    raw_cmd += ['--create_and_return']
    return self._run(board, pool, build, suite_name, timeout_s, raw_cmd)

  def wait_for_suite(self, task_id, board, pool, build, suite_name, timeout_s):
    """Wait for a suite previously kicked off via trigger_suite().

    @param task_id: Task ID of the suite, as returned by trigger_suite().
    @param board: The board autotest label of the DUTs.
    @param pool: The pool autotest label of the DUTs.
    @param build: The build to test, e.g. link-paladin/R70-10915.0.0-rc1.
    @param suite_name: The name of the suite to run, e.g. provision.
    @param timeout_s: Timeout for the suite, in seconds.
    @returns: The task ID of the kicked off suite.
    """
    raw_cmd = self._suite_cmd_common(board, pool, build, suite_name, timeout_s)
    raw_cmd += ['--suite_id', task_id]
    return self._run(board, pool, build, suite_name, timeout_s, raw_cmd)

  def _suite_cmd_common(self, board, pool, build, suite_name, timeout_s):
    return [
        _SKYLAB_RUN_SUITE_PATH,
        '--board', board,
        '--build', build,
        '--max_retries', '5',
        '--pool', _old_style_pool_label(pool),
        '--priority', str(_TEST_PUSH_SUITE_PRIORITY),
        '--suite_args', json.dumps({'num_required': 1}),
        '--suite_name', suite_name,
        '--test_retry',
        '--timeout_mins', str(int(timeout_s / 60)),
    ]

  def _run(self, board, pool, build, suite_name, timeout_s, raw_cmd):
    timeout_s = str(int(timeout_s))
    task_name = '%s-%s' % (build, suite_name)
    # This is a subset of the tags used by builders when creating suites.
    # These tags are used by the result reporting pipeline in various ways.
    tags = {
        'board': board,
        'build': build,
        # Required for proper rendering of MILO UI.
        'luci_project': 'chromeos',
        'skylab': 'run_suite',
        'skylab': 'staging',
        'suite': suite_name,
        'task_name': task_name,
    }
    osutils = autotest.chromite_load('osutils')
    with osutils.TempDir() as tempdir:
      summary_file = os.path.join(tempdir, 'summary.json')
      cmd = self._base_cmd('run') + [
          '--dimension', 'pool',  _SWARMING_POOL_SKYLAB_SUITE_BOTS,
          '--expiration', timeout_s,
          '--io-timeout', timeout_s,
          '--hard-timeout', timeout_s,
          '--print-status-update',
          '--priority', str(_TEST_PUSH_SUITE_PRIORITY),
          '--raw-cmd',
          '--task-name', task_name,
          '--task-summary-json', summary_file,
          '--timeout', timeout_s,
      ]
      for key, val in tags.iteritems():
        cmd += ['--tags', '%s:%s' % (key, val)]
      cmd += ['--'] + raw_cmd

      cros_build_lib = autotest.chromite_load('cros_build_lib')
      cros_build_lib.RunCommand(cmd, error_code_ok=True)
      return _extract_run_id(summary_file)


  def _base_cmd(self, subcommand):
    cmd = [
        self._cli_path, subcommand,
        '--swarming', self._host,
    ]
    if self._service_account_json is not None:
      cmd += ['--auth-service-account-json', self._service_account_json]
    return cmd


  def task_url(self, task_id):
    """Generate the task url based on task id."""
    return '%s/user/task/%s' % (self._host, task_id)


def _extract_run_id(path):
  if not os.path.isfile(path):
    raise errors.TestPushError('No task summary at %s' % path)
  with open(path) as f:
    summary = json.load(f)
  if not summary.get('shards') or len(summary['shards']) != 1:
    raise errors.TestPushError('Corrupted task summary at %s' % path)
  run_id = summary['shards'][0].get('run_id')
  if not run_id:
    raise errors.TestPushError('No run_id in task summary at %s' % path)
  return run_id


def _old_style_pool_label(label):
  _POOL_LABEL_PREFIX = 'dut_pool_'
  label = label.lower()
  if label.startswith(_POOL_LABEL_PREFIX):
    return label[len(_POOL_LABEL_PREFIX):]
  return label
