#!/usr/bin/python2.4
#
#
# Copyright 2007, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# System imports
import os
import signal
import subprocess
import threading
import time

# local imports
import errors
import logger

_abort_on_error = False

def SetAbortOnError(abort=True):
  """Sets behavior of RunCommand to throw AbortError if command process returns
  a negative error code"""
  global _abort_on_error
  _abort_on_error = abort

def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True,
               stdin_input=None):
  """Spawn and retry a subprocess to run the given shell command.

  Args:
    cmd: shell command to run
    timeout_time: time in seconds to wait for command to run before aborting.
    retry_count: number of times to retry command
    return_output: if True return output of command as string. Otherwise,
      direct output of command to stdout.
    stdin_input: data to feed to stdin
  Returns:
    output of command
  """
  result = None
  while True:
    try:
      result = RunOnce(cmd, timeout_time=timeout_time,
                       return_output=return_output, stdin_input=stdin_input)
    except errors.WaitForResponseTimedOutError:
      if retry_count == 0:
        raise
      retry_count -= 1
      logger.Log("No response for %s, retrying" % cmd)
    else:
      # Success
      return result

def RunOnce(cmd, timeout_time=None, return_output=True, stdin_input=None):
  """Spawns a subprocess to run the given shell command.

  Args:
    cmd: shell command to run
    timeout_time: time in seconds to wait for command to run before aborting.
    return_output: if True return output of command as string. Otherwise,
      direct output of command to stdout.
    stdin_input: data to feed to stdin
  Returns:
    output of command
  Raises:
    errors.WaitForResponseTimedOutError if command did not complete within
      timeout_time seconds.
    errors.AbortError is command returned error code and SetAbortOnError is on.
  """
  start_time = time.time()
  so = []
  pid = []
  global _abort_on_error, error_occurred
  error_occurred = False

  def Run():
    global error_occurred
    if return_output:
      output_dest = subprocess.PIPE
    else:
      # None means direct to stdout
      output_dest = None
    if stdin_input:
      stdin_dest = subprocess.PIPE
    else:
      stdin_dest = None
    pipe = subprocess.Popen(
        cmd,
        executable='/bin/bash',
        stdin=stdin_dest,
        stdout=output_dest,
        stderr=subprocess.STDOUT,
        shell=True)
    pid.append(pipe.pid)
    try:
      output = pipe.communicate(input=stdin_input)[0]
      if output is not None and len(output) > 0:
        so.append(output)
    except OSError, e:
      logger.SilentLog("failed to retrieve stdout from: %s" % cmd)
      logger.Log(e)
      so.append("ERROR")
      error_occurred = True
    if pipe.returncode:
      logger.SilentLog("Error: %s returned %d error code" %(cmd,
          pipe.returncode))
      error_occurred = True

  t = threading.Thread(target=Run)
  t.start()

  break_loop = False
  while not break_loop:
    if not t.isAlive():
      break_loop = True

    # Check the timeout
    if (not break_loop and timeout_time is not None
        and time.time() > start_time + timeout_time):
      try:
        os.kill(pid[0], signal.SIGKILL)
      except OSError:
        # process already dead. No action required.
        pass

      logger.SilentLog("about to raise a timeout for: %s" % cmd)
      raise errors.WaitForResponseTimedOutError
    if not break_loop:
      time.sleep(0.1)

  t.join()
  output = "".join(so)
  if _abort_on_error and error_occurred:
    raise errors.AbortError(msg=output)

  return "".join(so)


def RunHostCommand(binary, valgrind=False):
  """Run a command on the host (opt using valgrind).

  Runs the host binary and returns the exit code.
  If successfull, the output (stdout and stderr) are discarded,
  but printed in case of error.
  The command can be run under valgrind in which case all the
  output are always discarded.

  Args:
    binary: full path of the file to be run.
    valgrind: If True the command will be run under valgrind.

  Returns:
    The command exit code (int)
  """
  if not valgrind:
    subproc = subprocess.Popen(binary, stdout=subprocess.PIPE,
                               stderr=subprocess.STDOUT)
    subproc.wait()
    if subproc.returncode != 0:         # In case of error print the output
      print subproc.communicate()[0]
    return subproc.returncode
  else:
    # Need the full path to valgrind to avoid other versions on the system.
    subproc = subprocess.Popen(["/usr/bin/valgrind", "--tool=memcheck",
                                "--leak-check=yes", "-q", binary],
                               stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    # Cannot rely on the retcode of valgrind. Instead look for an empty output.
    valgrind_out = subproc.communicate()[0].strip()
    if valgrind_out:
      print valgrind_out
      return 1
    else:
      return 0


def HasValgrind():
  """Check that /usr/bin/valgrind exists.

  We look for the fullpath to avoid picking up 'alternative' valgrind
  on the system.

  Returns:
    True if a system valgrind was found.
  """
  return os.path.exists("/usr/bin/valgrind")
