# Copyright (c) 2010 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.

"""Common python commands used by various build scripts."""

import inspect
import os
import re
import subprocess
import sys

_STDOUT_IS_TTY = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()

# TODO(sosa):  Move logging to logging module.

class RunCommandException(Exception):
  """Raised when there is an error in RunCommand."""
  pass


def GetCallerName():
  """Returns the name of the calling module with __main__."""
  top_frame = inspect.stack()[-1][0]
  return os.path.basename(top_frame.f_code.co_filename)


def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None,
               exit_code=False, redirect_stdout=False, redirect_stderr=False,
               cwd=None, input=None, enter_chroot=False, num_retries=0,
               log_to_file=None, combine_stdout_stderr=False):
  """Runs a shell command.

  Arguments:
    cmd: cmd to run.  Should be input to subprocess.POpen.  If a string,
      converted to an array using split().
    print_cmd: prints the command before running it.
    error_ok: does not raise an exception on error.
    error_message: prints out this message when an error occurrs.
    exit_code: returns the return code of the shell command.
    redirect_stdout: returns the stdout.
    redirect_stderr: holds stderr output until input is communicated.
    cwd: the working directory to run this cmd.
    input: input to pipe into this command through stdin.
    enter_chroot: this command should be run from within the chroot.  If set,
      cwd must point to the scripts directory.
    num_retries: the number of retries to perform before dying
    log_to_file: Redirects all stderr and stdout to file specified by this path.
    combine_stdout_stderr: Combines stdout and stdin streams into stdout. Auto
      set to true if log_to_file specifies a file.

  Returns:
    If exit_code is True, returns the return code of the shell command.
    Else returns the output of the shell command.

  Raises:
    Exception:  Raises RunCommandException on error with optional error_message,

                but only if exit_code, and error_ok are both False. 
  """
  # Set default for variables.
  stdout = None
  stderr = None
  stdin = None
  file_handle = None
  output = ''

  # Modify defaults based on parameters.
  if log_to_file:
    file_handle = open(log_to_file, 'w+')
    stdout = file_handle
    stderr = file_handle
  else:
    if redirect_stdout:  stdout = subprocess.PIPE
    if redirect_stderr:  stderr = subprocess.PIPE
    if combine_stdout_stderr: stderr = subprocess.STDOUT

  if input:  stdin = subprocess.PIPE
  if enter_chroot:  cmd = ['cros_sdk', '--'] + cmd

  # Print out the command before running.
  cmd_string = 'PROGRAM(%s) -> RunCommand: %r in dir %s' % (GetCallerName(),
                                                            cmd, cwd)
  if print_cmd:
    if not log_to_file:
      Info(cmd_string)
    else:
      Info('%s -- Logging to %s' % (cmd_string, log_to_file))

  for retry_count in range(num_retries + 1):

    # If it's not the first attempt, it's a retry
    if retry_count > 0 and print_cmd:
      Info('PROGRAM(%s) -> RunCommand: retrying %r in dir %s' %
           (GetCallerName(), cmd, cwd))

    proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin,
                            stdout=stdout, stderr=stderr, close_fds=True)
    (output, error) = proc.communicate(input)

    # if the command worked, don't retry any more.
    if proc.returncode == 0:
      break

  if file_handle: file_handle.close()

  # If they asked for an exit_code, give it to them on success or failure
  if exit_code:
    return proc.returncode

  # If the command (and all retries) failed, handle error result
  if proc.returncode != 0 and not error_ok:
    if output:
      print >> sys.stderr, output
      sys.stderr.flush()

    error_info = ('Command "%r" failed.\n' % (cmd) +
                  (error_message or error or ''))
    if log_to_file: error_info += '\nOutput logged to %s' % log_to_file
    raise RunCommandException(error_info)

  # return final result
  return output


def RunCommandCaptureOutput(cmd, print_cmd=True, cwd=None, input=None,
                            enter_chroot=False,
                            combine_stdout_stderr=True,
                            verbose=False):
  """Runs a shell command. Differs from RunCommand, because it allows
     you to run a command and capture the exit code, output, and stderr
     all at the same time.

  Arguments:
    cmd: cmd to run.  Should be input to subprocess.POpen.  If a string,
      converted to an array using split().
    print_cmd: prints the command before running it.
    cwd: the working directory to run this cmd.
    input: input to pipe into this command through stdin.
    enter_chroot: this command should be run from within the chroot.  If set,
      cwd must point to the scripts directory.
    combine_stdout_stderr -- combine outputs together.
    verbose -- also echo cmd.stdout and cmd.stderr to stdout and stderr

  Returns:
    Returns a tuple: (exit_code, stdout, stderr) (integer, string, string)
    stderr is None if combine_stdout_stderr is True
  """
  # Set default for variables.
  stdout = subprocess.PIPE
  stderr = subprocess.PIPE
  stdin = None

  # Modify defaults based on parameters.
  if input:  stdin = subprocess.PIPE
  if combine_stdout_stderr: stderr = subprocess.STDOUT

  if enter_chroot:  cmd = ['cros_sdk', '--'] + cmd

  # Print out the command before running.
  if print_cmd:
    Info('PROGRAM(%s) -> RunCommand: %r in dir %s' %
         (GetCallerName(), cmd, cwd))

  proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin,
                          stdout=stdout, stderr=stderr, close_fds=True)
  output, error = proc.communicate(input)

  if verbose:
    if output: sys.stdout.write(output)
    if error: sys.stderr.write(error)

  # Error is None if stdout, stderr are combined.
  return proc.returncode, output, error


class Color(object):
  """Conditionally wraps text in ANSI color escape sequences."""
  BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
  BOLD = -1
  COLOR_START = '\033[1;%dm'
  BOLD_START = '\033[1m'
  RESET = '\033[0m'

  def __init__(self, enabled=True):
    self._enabled = enabled

  def Color(self, color, text):
    """Returns text with conditionally added color escape sequences.

    Keyword arguments:
      color: Text color -- one of the color constants defined in this class.
      text: The text to color.

    Returns:
      If self._enabled is False, returns the original text. If it's True,
      returns text with color escape sequences based on the value of color.
    """
    if not self._enabled:
      return text
    if color == self.BOLD:
      start = self.BOLD_START
    else:
      start = self.COLOR_START % (color + 30)
    return start + text + self.RESET


def Die(message):
  """Emits a red error message and halts execution.

  Keyword arguments:
    message: The message to be emitted before exiting.
  """
  print >> sys.stderr, (
      Color(_STDOUT_IS_TTY).Color(Color.RED, '\nERROR: ' + message))
  sys.stderr.flush()
  sys.exit(1)


def Warning(message):
  """Emits a yellow warning message and continues execution.

  Keyword arguments:
    message: The message to be emitted.
  """
  print >> sys.stderr, (
      Color(_STDOUT_IS_TTY).Color(Color.YELLOW, '\nWARNING: ' + message))
  sys.stderr.flush()


def Info(message):
  """Emits a blue informational message and continues execution.

  Keyword arguments:
    message: The message to be emitted.
  """
  print >> sys.stderr, (
      Color(_STDOUT_IS_TTY).Color(Color.BLUE, '\nINFO: ' + message))
  sys.stderr.flush()


def FindRepoDir(path=None):
  """Returns the nearest higher-level repo dir from the specified path.

  Args:
    path: The path to use. Defaults to cwd.
  """
  if path is None:
    path = os.getcwd()
  path = os.path.abspath(path)
  while path != '/':
    repo_dir = os.path.join(path, '.repo')
    if os.path.isdir(repo_dir):
      return repo_dir
    path = os.path.dirname(path)
  return None


def ReinterpretPathForChroot(path):
  """Returns reinterpreted path from outside the chroot for use inside.

  Keyword arguments:
    path: The path to reinterpret.  Must be in src tree.
  """
  root_path = os.path.join(FindRepoDir(path), '..')

  path_abs_path = os.path.abspath(path)
  root_abs_path = os.path.abspath(root_path)

  # Strip the repository root from the path and strip first /.
  relative_path = path_abs_path.replace(root_abs_path, '')[1:]

  if relative_path == path_abs_path:
    raise Exception('Error: path is outside your src tree, cannot reinterpret.')

  new_path = os.path.join('/home', os.getenv('USER'), 'trunk', relative_path)
  return new_path


def PrependChrootPath(path):
  """Assumes path is a chroot path and prepends chroot to create full path."""
  chroot_path = os.path.join(FindRepoDir(), '..', 'chroot')
  if path.startswith('/'):
    return os.path.realpath(os.path.join(chroot_path, path[1:]))
  else:
    return os.path.realpath(os.path.join(chroot_path, path))


def GetIPAddress(device='eth0'):
  """Returns the IP Address for a given device using ifconfig.

  socket.gethostname() is insufficient for machines where the host files are
  not set up "correctly."  Since some of our builders may have this issue,
  this method gives you a generic way to get the address so you are reachable
  either via a VM or remote machine on the same network.
  """
  ifconfig_output = RunCommand(['/sbin/ifconfig', device],
                               redirect_stdout=True, print_cmd=False)
  match = re.search('.*inet addr:(\d+\.\d+\.\d+\.\d+).*', ifconfig_output)
  if match:
    return match.group(1)
  else:
    Warning('Failed to find ip address in %s' % ifconfig_output)
    return None


def MountImage(image_path, root_dir, stateful_dir, read_only):
  """Mounts a Chromium OS image onto mount dir points."""
  from_dir = os.path.dirname(image_path)
  image = os.path.basename(image_path)
  extra_args = []
  if read_only: extra_args.append('--read_only')
  cmd = ['./mount_gpt_image.sh',
         '--from=%s' % from_dir,
         '--image=%s' % image,
         '--rootfs_mountpt=%s' % root_dir,
         '--stateful_mountpt=%s' % stateful_dir,
        ]
  cmd.extend(extra_args)
  RunCommand(cmd, print_cmd=False, redirect_stdout=True, redirect_stderr=True,
             cwd=CROSUTILS_DIRECTORY)


def UnmountImage(root_dir, stateful_dir):
  """Unmounts a Chromium OS image specified by mount dir points."""
  RunCommand(['./mount_gpt_image.sh',
              '--unmount',
              '--rootfs_mountpt=%s' % root_dir,
              '--stateful_mountpt=%s' % stateful_dir,
             ], print_cmd=False, redirect_stdout=True, redirect_stderr=True,
             cwd=CROSUTILS_DIRECTORY)


def GetCrosUtilsPath(source_dir_path=True):
  """Return the path to src/scripts.

  Args:
    source_dir_path:  If True, returns the path from the source code directory.
  """
  if IsInsideChroot():
    if source_dir_path:
      return os.path.join(os.getenv('HOME'), 'trunk', 'src', 'scripts')

    return os.path.join('/usr/lib/crosutils')

  # Outside the chroot => from_source.
  return os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')


def GetCrosUtilsBinPath(source_dir_path=True):
  """Return the path to crosutils/bin.

  Args:
    source_dir_path:  If True, returns the path from the source code directory.
  """
  if IsInsideChroot() and not source_dir_path:
      return '/usr/bin'

  return os.path.join(GetCrosUtilsPath(source_dir_path), 'bin')


def IsInsideChroot():
  """Returns True if we are inside chroot."""
  return os.path.exists('/etc/debian_chroot')


# TODO(sosa): Remove once all callers use method.
CROSUTILS_DIRECTORY = GetCrosUtilsPath(True)
