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

"""Module that contains the interface for au_test_harness workers.

An au test harnss worker is a class that contains the logic for performing
and validating updates on a target.  This should be subclassed to handle
various types of target.  Types of targets include VM's, real devices, etc.
"""

import inspect
import threading
import os
import sys

import cros_build_lib as cros_lib

import dev_server_wrapper
import update_exception


class AUWorker(object):
  """Interface for a worker that updates and verifies images."""
  # Mapping between cached payloads to directory locations.
  update_cache = None

  # --- INTERFACE ---

  def __init__(self, options, test_results_root):
    """Processes options for the specific-type of worker."""
    self.board = options.board
    self.private_key = options.private_key
    self.test_results_root = test_results_root
    self.use_delta_updates = options.delta
    self.verbose = options.verbose
    self.vm_image_path = None
    if options.quick_test:
      self.verify_suite = 'build_RootFilesystemSize'
    else:
      self.verify_suite = 'suite_Smoke'

    # Set these up as they are used often.
    self.crosutils = cros_lib.GetCrosUtilsPath()
    self.crosutilsbin = cros_lib.GetCrosUtilsBinPath()

  def CleanUp(self):
    """Called at the end of every test."""
    pass

  def GetUpdateMessage(self, update_target, update_base, from_vm, proxy):
    if update_base:
      str = 'Performing a delta update from %s to %s' % (
          update_base, update_target)
    else:
      str = 'Performing a full update to %s' % update_target

    if from_vm: str += ' in a VM'
    if proxy: ' using a proxy on port %s' % proxy
    return str

  def UpdateImage(self, image_path, src_image_path='', stateful_change='old',
                  proxy_port=None, private_key_path=None):
    """Implementation of an actual update.

    See PerformUpdate for description of args.  Subclasses must override this
    method with the correct update procedure for the class.
    """
    pass

  def UpdateUsingPayload(self, update_path, stateful_change='old',
                         proxy_port=None):
    """Updates target with the pre-generated update stored in update_path.

    Subclasses must override this method with the correct update procedure for
    the class.

    Args:
      update_path:  Path to the image to update with. This directory should
        contain both update.gz, and stateful.image.gz
      proxy_port:  Port to have the client connect to. For use with
        CrosTestProxy.
    """
    pass

  def VerifyImage(self, unittest, percent_required_to_pass=100, test=''):
    """Verifies the image with tests.

    Verifies that the test images passes the percent required.  Subclasses must
    override this method with the correct update procedure for the class.

    Args:
      unittest: pointer to a unittest to fail if we cannot verify the image.
      percent_required_to_pass:  percentage required to pass.  This should be
        fall between 0-100.
      test: test that will be used to verify the image. If omitted or equal to
        the empty string the code will use self.verify_suite.

    Returns:
      Returns the percent that passed.
    """
    pass

  # --- INTERFACE TO AU_TEST ---

  def PerformUpdate(self, image_path, src_image_path='', stateful_change='old',
                    proxy_port=None, private_key_path=None):
    """Performs an update using  _UpdateImage and reports any error.

    Subclasses should not override this method but override _UpdateImage
    instead.

    Args:
      image_path:  Path to the image to update with.  This image must be a test
        image.
      src_image_path:  Optional.  If set, perform a delta update using the
        image specified by the path as the source image.
      stateful_change: How to modify the stateful partition.  Values are:
          'old':  Don't modify stateful partition.  Just update normally.
          'clean':  Uses clobber-state to wipe the stateful partition with the
            exception of code needed for ssh.
      proxy_port:  Port to have the client connect to. For use with
        CrosTestProxy.
      private_key_path:  Path to a private key to use with update payload.
    Raises an update_exception.UpdateException if _UpdateImage returns an error.
    """
    if not self.use_delta_updates: src_image_path = ''
    if private_key_path:
      key_to_use = private_key_path
    else:
      key_to_use = self.private_key

    self.UpdateImage(image_path, src_image_path, stateful_change,
                            proxy_port, key_to_use)

  @classmethod
  def SetUpdateCache(cls, update_cache):
    """Sets the global update cache for getting paths to devserver payloads."""
    cls.update_cache = update_cache

  # --- METHODS FOR SUB CLASS USE ---

  def PrepareRealBase(self, image_path):
    """Prepares a remote device for worker test by updating it to the image."""
    self.UpdateImage(image_path)

  def PrepareVMBase(self, image_path):
    """Prepares a VM image for worker test by creating the VM file from the img.
    """
    # VM Constants.
    FULL_VDISK_SIZE = 6072
    FULL_STATEFULFS_SIZE = 3074
    # Needed for VM delta updates.  We need to use the qemu image rather
    # than the base image on a first update.  By tracking the first_update
    # we can set src_image to the qemu form of the base image when
    # performing generating the delta payload.
    self._first_update = True
    self.vm_image_path = '%s/chromiumos_qemu_image.bin' % os.path.dirname(
        image_path)
    if not os.path.exists(self.vm_image_path):
      cros_lib.Info('Creating %s' % self.vm_image_path)
      cros_lib.RunCommand(['./image_to_vm.sh',
                           '--full',
                           '--from=%s' % cros_lib.ReinterpretPathForChroot(
                               os.path.dirname(image_path)),
                           '--vdisk_size=%s' % FULL_VDISK_SIZE,
                           '--statefulfs_size=%s' % FULL_STATEFULFS_SIZE,
                           '--board=%s' % self.board,
                           '--test_image'
                          ], enter_chroot=True, cwd=self.crosutils)

    assert os.path.exists(self.vm_image_path)

  def GetStatefulChangeFlag(self, stateful_change):
    """Returns the flag to pass to image_to_vm for the stateful change."""
    stateful_change_flag = ''
    if stateful_change:
      stateful_change_flag = '--stateful_update_flag=%s' % stateful_change

    return stateful_change_flag

  def AppendUpdateFlags(self, cmd, image_path, src_image_path, proxy_port,
                        private_key_path):
    """Appends common args to an update cmd defined by an array.

    Modifies cmd in places by appending appropriate items given args.
    """
    if proxy_port: cmd.append('--proxy_port=%s' % proxy_port)
    # Get pregenerated update if we have one.
    update_id = dev_server_wrapper.GenerateUpdateId(image_path, src_image_path,
                                                    private_key_path)
    cache_path = self.update_cache[update_id]
    if cache_path:
      update_url = dev_server_wrapper.DevServerWrapper.GetDevServerURL(
          proxy_port, cache_path)
      cmd.append('--update_url=%s' % update_url)
    else:
      cmd.append('--image=%s' % image_path)
      if src_image_path: cmd.append('--src_image=%s' % src_image_path)

  def RunUpdateCmd(self, cmd, log_directory=None):
    """Runs the given update cmd given verbose options.

    Raises an update_exception.UpdateException if the update fails.
    """
    if self.verbose:
      try:
        if log_directory:
          cros_lib.RunCommand(
              cmd, log_to_file=os.path.join(log_directory, 'update.log'),
              print_cmd=False)
        else:
          cros_lib.RunCommand(cmd, print_cmd=False)
      except cros_lib.RunCommandException as e:
        raise update_exception.UpdateException(1, str(e))
    else:
      (code, stdout, unused_stderr) = cros_lib.RunCommandCaptureOutput(
          cmd, print_cmd=False)
      if code != 0:
        cros_lib.Warning(stdout)
        raise update_exception.UpdateException(code, 'Update cmd failed')

  def AssertEnoughTestsPassed(self, unittest, output, percent_required_to_pass):
    """Helper function that asserts a sufficient number of tests passed.

    Args:
      output: stdout from a test run.
      percent_required_to_pass: percentage required to pass.  This should be
        fall between 0-100.
    Returns:
      percent that passed.
    """
    percent_passed = self._ParseGenerateTestReportOutput(output)
    self.TestInfo('Percent passed: %d vs. Percent required: %d' % (
        percent_passed, percent_required_to_pass))
    if percent_passed < percent_required_to_pass:
      print output
      unittest.fail('%d percent of tests are required to pass' %
                    percent_required_to_pass)

    return percent_passed

  def TestInfo(self, message):
    cros_lib.Info('%s: %s' % (self.test_name, message))

  def Initialize(self, port):
    """Initializes test specific variables for each test.

    Each test needs to specify a unique ssh port.

    Args:
      port:  Unique port for ssh access.
    """
    # Initialize port vars.
    self._ssh_port = port
    self._kvm_pid_file = '/tmp/kvm.%d' % port

    # Initialize test results directory.
    self.test_name = inspect.stack()[1][3]
    self.results_directory = os.path.join(self.test_results_root,
                                          self.test_name)
    self.results_count = 0

  def GetNextResultsPath(self, label):
    """Returns a path for the results directory for this label.

    Prefixes directory returned for worker with time called i.e. 1_label,
    2_label, etc.  The directory returned is outside the chroot so if passing
    to an script that is called with enther_chroot, make sure to use
    ReinterpretPathForChroot.
    """
    self.results_count += 1
    dir = os.path.join(self.results_directory, '%s_%s' % (self.results_count,
                                                          label))
    if not os.path.exists(dir):
      os.makedirs(dir)

    return dir

  # --- PRIVATE HELPER FUNCTIONS ---

  def _ParseGenerateTestReportOutput(self, output):
    """Returns the percentage of tests that passed based on output."""
    percent_passed = 0
    lines = output.split('\n')

    for line in lines:
      if line.startswith("Total PASS:"):
        # FORMAT: ^TOTAL PASS: num_passed/num_total (percent%)$
        percent_passed = line.split()[3].strip('()%')
        break

    return int(percent_passed)
