# 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.

"""Operation, including output and progress display

This module implements the concept of an operation, which has regular progress
updates, verbose text display and perhaps some errors.
"""

from __future__ import print_function

import collections
import contextlib
import fcntl
import multiprocessing
import os
import pty
try:
  import Queue
except ImportError:
  # Python-3 renamed to "queue".  We still use Queue to avoid collisions
  # with naming variables as "queue".  Maybe we'll transition at some point.
  # pylint: disable=import-error
  import queue as Queue
import re
import shutil
import struct
import sys
import termios

from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import workspace_lib
from chromite.lib.terminal import Color


_TerminalSize = collections.namedtuple('_TerminalSize', ('lines', 'columns'))


class _BackgroundTaskComplete(object):
  """Sentinal object to indicate that the background task is complete."""


class ProgressBarOperation(object):
  """Wrapper around long running functions to show progress.

  This class is intended to capture the output of a long running fuction, parse
  the output, and display a progress bar.

  To display a progress bar for a function foo with argument foo_args, this is
  the usage case:
    1) Create a class that inherits from ProgressBarOperation (e.g.
    FooTypeOperation. In this class, override the ParseOutput method to parse
    the output of foo.
    2) op = operation.FooTypeOperation()
       op.Run(foo, foo_args)
  """

  # Subtract 10 characters from the width of the terminal because these are used
  # to display the percentage as well as other spaces.
  _PROGRESS_BAR_BORDER_SIZE = 10

  # By default, update the progress bar every 100 ms.
  _PROGRESS_BAR_UPDATE_INTERVAL = 0.1

  def __init__(self):
    self._queue = multiprocessing.Queue()
    self._stderr = None
    self._stdout = None
    self._stdout_path = None
    self._stderr_path = None
    self._progress_bar_displayed = False
    self._workspace_path = workspace_lib.WorkspacePath()
    self._isatty = os.isatty(sys.stdout.fileno())

  def _GetTerminalSize(self, fd=pty.STDOUT_FILENO):
    """Return a terminal size object for |fd|.

    Note: Replace with os.terminal_size() in python3.3.
    """
    winsize = struct.pack('HHHH', 0, 0, 0, 0)
    data = fcntl.ioctl(fd, termios.TIOCGWINSZ, winsize)
    winsize = struct.unpack('HHHH', data)
    return _TerminalSize(int(winsize[0]), int(winsize[1]))

  def ProgressBar(self, progress):
    """This method creates and displays a progress bar.

    If not in a terminal, we do not display a progress bar.

    Args:
      progress: a float between 0 and 1 that represents the fraction of the
        current progress.
    """
    if not self._isatty:
      return
    self._progress_bar_displayed = True
    progress = max(0.0, min(1.0, progress))
    width = max(1, self._GetTerminalSize().columns -
                self._PROGRESS_BAR_BORDER_SIZE)
    block = int(width * progress)
    shaded = '#' * block
    unshaded = '-' * (width - block)
    text = '\r [%s%s] %d%%' % (shaded, unshaded, progress * 100)
    sys.stdout.write(text)
    sys.stdout.flush()

  def OpenStdoutStderr(self):
    """Open the stdout and stderr streams."""
    if self._stdout is None and self._stderr is None:
      self._stdout = open(self._stdout_path, 'r')
      self._stderr = open(self._stderr_path, 'r')

  def Cleanup(self):
    """Method to cleanup progress bar.

    If progress bar has been printed, then we make sure it displays 100% before
    exiting.
    """
    if self._progress_bar_displayed:
      self.ProgressBar(1)
      sys.stdout.write('\n')
      sys.stdout.flush()

  def ParseOutput(self, output=None):
    """Method to parse output and update progress bar.

    This method should be overridden to read and parse the lines in _stdout and
    _stderr.

    One example use of this method could be to detect 'foo' in stdout and
    increment the progress bar every time foo is seen.

    def ParseOutput(self):
      stdout = self._stdout.read()
      if 'foo' in stdout:
        # Increment progress bar.

    Args:
      output: Pass in output to parse instead of reading from self._stdout and
        self._stderr.
    """
    raise NotImplementedError('Subclass must override this method.')

  # TODO(ralphnathan): Deprecate this function and use parallel._BackgroundTask
  # instead (brbug.com/863)
  def WaitUntilComplete(self, update_period):
    """Return True if running background task has completed."""
    try:
      x = self._queue.get(timeout=update_period)
      if isinstance(x, _BackgroundTaskComplete):
        return True
    except Queue.Empty:
      return False

  def CaptureOutputInBackground(self, func, *args, **kwargs):
    """Launch func in background and capture its output.

    Args:
      func: Function to execute in the background and whose output is to be
        captured.
      log_level: Logging level to run the func at. By default, it runs at log
        level info.
    """
    log_level = kwargs.pop('log_level', logging.INFO)
    restore_log_level = logging.getLogger().getEffectiveLevel()
    logging.getLogger().setLevel(log_level)
    try:
      with cros_build_lib.OutputCapturer(
          stdout_path=self._stdout_path, stderr_path=self._stderr_path,
          quiet_fail=self._workspace_path is not None):
        func(*args, **kwargs)
    finally:
      self._queue.put(_BackgroundTaskComplete())
      logging.getLogger().setLevel(restore_log_level)

  def MoveStdoutStderrFiles(self):
    """On failure, move stdout/stderr files to workspace/WORKSPACE_LOGS_DIR."""
    path = os.path.join(self._workspace_path, workspace_lib.WORKSPACE_LOGS_DIR)
    # TODO(ralphnathan): Not sure if we need this because it should be done when
    # we store the log file for brillo commands.
    osutils.SafeMakedirs(path)
    shutil.move(self._stdout_path, path)
    shutil.move(self._stderr_path, path)
    logging.warning('Please look at %s for more information.', path)

  # TODO (ralphnathan): Store PID of spawned process.
  def Run(self, func, *args, **kwargs):
    """Run func, parse its output, and update the progress bar.

    Args:
      func: Function to execute in the background and whose output is to be
        captured.
      upadate_period: Optional argument to specify the period that output should
        be read.
    """
    update_period = kwargs.pop('update_period',
                               self._PROGRESS_BAR_UPDATE_INTERVAL)

    # If we are not running in a terminal device, do not display the progress
    # bar.
    if not self._isatty:
      func(*args, **kwargs)
      return

    with osutils.TempDir() as tempdir:
      self._stdout_path = os.path.join(tempdir, 'stdout')
      self._stderr_path = os.path.join(tempdir, 'stderr')
      osutils.Touch(self._stdout_path)
      osutils.Touch(self._stderr_path)
      try:
        with parallel.BackgroundTaskRunner(
            self.CaptureOutputInBackground, func, *args, **kwargs) as queue:
          queue.put([])
          self.OpenStdoutStderr()
          while True:
            self.ParseOutput()
            if self.WaitUntilComplete(update_period):
              break
        # Before we exit, parse the output again to update progress bar.
        self.ParseOutput()
        # Final sanity check to update the progress bar to 100% if it was used
        # by ParseOutput
        self.Cleanup()
      except:
        logging.error('Oops. Something went wrong.')
        # Move the stdout/stderr files to a location that the user can access.
        if self._workspace_path is not None:
          self.MoveStdoutStderrFiles()
        # Raise the exception so it can be caught again.
        raise


class ParallelEmergeOperation(ProgressBarOperation):
  """ProgressBarOperation specific for scripts/parallel_emerge.py."""

  def __init__(self):
    super(ParallelEmergeOperation, self).__init__()
    self._total = None
    self._completed = 0
    self._printed_no_packages = False
    self._events = ['Fetched ', 'Completed ']
    self._msg = None

  def _GetTotal(self, output):
    """Get total packages by looking for Total: digits packages."""
    match = re.search(r'Total: (\d+) packages', output)
    return int(match.group(1)) if match else None

  def SetProgressBarMessage(self, msg):
    """Message to be shown before the progress bar is displayed with 0%.

       The message is not displayed if the progress bar is not going to be
       displayed.
    """
    self._msg = msg

  def ParseOutput(self, output=None):
    """Parse the output of emerge to determine how to update progress bar.

    1) Figure out how many packages exist. If the total number of packages to be
    built is zero, then we do not display the progress bar.
    2) Whenever a package is downloaded or built, 'Fetched' and 'Completed' are
    printed respectively. By counting counting 'Fetched's and 'Completed's, we
    can determine how much to update the progress bar by.

    Args:
      output: Pass in output to parse instead of reading from self._stdout and
        self._stderr.

    Returns:
      A fraction between 0 and 1 indicating the level of the progress bar. If
      the progress bar isn't displayed, then the return value is -1.
    """
    if output is None:
      stdout = self._stdout.read()
      stderr = self._stderr.read()
      output = stdout + stderr

    if self._total is None:
      temp = self._GetTotal(output)
      if temp is not None:
        self._total = temp * len(self._events)
        if self._msg is not None:
          logging.notice(self._msg)

    for event in self._events:
      self._completed += output.count(event)

    if not self._printed_no_packages and self._total == 0:
      logging.notice('No packages to build.')
      self._printed_no_packages = True

    if self._total:
      progress = float(self._completed) / self._total
      self.ProgressBar(progress)
      return progress
    else:
      return -1


# TODO(sjg): When !isatty(), keep stdout and stderr separate so they can be
# redirected separately
# TODO(sjg): Add proper docs to this fileno
# TODO(sjg): Handle stdin wait in quite mode, rather than silently stalling

class Operation(object):
  """Class which controls stdio and progress of an operation in progress.

  This class is created to handle stdio for a running subprocess. It filters
  it looking for errors and progress information. Optionally it can output the
  stderr and stdout to the terminal, but it is normally supressed.

  Progress information is garnered from the subprocess output based on
  knowledge of the legacy scripts, but at some point will move over to using
  real progress information reported through new python methods which will
  replace the scripts.

  Each operation has a name, and this class handles displaying this name
  as it reports progress.

  Operation Objects
  =================

  verbose: True / False
    In verbose mode all output from subprocesses is displayed, otherwise
    this output is normally supressed, unless we think it indicates an error.

  progress: True / False
    The output from subprocesses can be analysed in a very basic manner to
    try to present progress information to the user.

  explicit_verbose: True / False
    False if we are not just using default verbosity. In that case we allow
    verbosity to be enabled on request, since the user has not explicitly
    disabled it. This is used by commands that the user issues with the
    expectation that output would ordinarily be visible.
  """

  def __init__(self, name, color=None):
    """Create a new operation.

    Args:
      name: Operation name in a form to be displayed for the user.
      color: Determines policy for sending color to stdout; see terminal.Color
        for details on interpretation on the value.
    """
    self._name = name   # Operation name.
    self.verbose = False   # True to echo subprocess output.
    self.progress = True   # True to report progress of the operation
    self._column = 0    # Current output column (always 0 unless verbose).
    self._update_len = 0    # Length of last progress update message.
    self._line = ''   # text of current line, so far
    self.explicit_verbose = False

    self._color = Color(enabled=color)

    # -1 = no newline pending
    #  n = newline pending, and line length of last line was n
    self._pending_nl = -1

    # the type of the last stream to emit data on the current lines
    # can be sys.stdout, sys.stderr (both from the subprocess), or None
    # for our own mesages
    self._cur_stream = None

    self._error_count = 0   # number of error lines we have reported

  def __del__(self):
    """Object is about to be destroyed, so finish out output cleanly."""
    self.FinishOutput()

  def FinishOutput(self):
    """Finish off any pending output.

    This finishes any output line currently in progress and resets the color
    back to normal.
    """
    self._FinishLine(self.verbose, final=True)
    if self._column and self.verbose:
      print(self._color.Stop())
      self._column = 0

  def WereErrorsDetected(self):
    """Returns whether any errors have been detected.

    Returns:
      True if any errors have been detected in subprocess output so far.
      False otherwise
    """
    return self._error_count > 0

  def SetName(self, name):
    """Set the name of the operation as displayed to the user.

    Args:
      name: Operation name.
    """
    self._name = name

  def _FilterOutputForErrors(self, line, print_error):
    """Filter a line of output to look for and display errors.

    This uses a few regular expression searches to spot common error reports
    from subprocesses. A count of these is kept so we know how many occurred.
    Optionally they are displayed in red on the terminal.

    Args:
      line: the output line to filter, as a string.
      print_error: True to print the error, False to just record it.
    """
    bad_things = ['Cannot GET', 'ERROR', '!!!', 'FAILED']
    for bad_thing in bad_things:
      if re.search(bad_thing, line, flags=re.IGNORECASE):
        self._error_count += 1
        if print_error:
          print(self._color.Color(self._color.RED, line))
          break

  def _FilterOutputForProgress(self, line):
    """Filter a line of output to look for and dispay progress information.

    This uses a simple regular expression search to spot progress information
    coming from subprocesses. This is sent to the _Progress() method.

    Args:
      line: the output line to filter, as a string.
    """
    match = re.match(r'Pending (\d+).*Total (\d+)', line)
    if match:
      pending = int(match.group(1))
      total = int(match.group(2))
      self._Progress(total - pending, total)

  def _Progress(self, upto, total):
    """Record and optionally display progress information.

    Args:
      upto: which step we are up to in the operation (integer, from 0).
      total: total number of steps in operation,
    """
    if total > 0:
      update_str = '%s...%d%% (%d of %d)' % (self._name,
                                             upto * 100 // total, upto, total)
      if self.progress:
        # Finish the current line, print progress, and remember its length.
        self._FinishLine(self.verbose)

        # Sometimes the progress string shrinks and in this case we need to
        # blank out the characters at the end of the line that will not be
        # overwritten by the new line
        pad = max(self._update_len - len(update_str), 0)
        sys.stdout.write(update_str + (' ' * pad) + '\r')
        self._update_len = len(update_str)

  def _FinishLine(self, display, final=False):
    """Finish off the current line and prepare to start a new one.

    If a new line is pending from the previous line, then this will be output,
    along with a color reset if needed.

    We also handle removing progress messages from the output. This is done
    using a carriage return character, following by spaces.

    Args:
      display: True to display output, False to suppress it
      final: True if this is the final output before we exit, in which case
          we must clean up any remaining progress message by overwriting
          it with spaces, then carriage return
    """
    if display:
      if self._pending_nl != -1:
        # If out last output line was shorter than the progress info
        # add spaces.
        if self._pending_nl < self._update_len:
          print(' ' * (self._update_len - self._pending_nl), end='')

        # Output the newline, and reset our counter.
        sys.stdout.write(self._color.Stop())
        print()

    # If this is the last thing that this operation will print, we need to
    # close things off. So if there is some text on the current line but not
    # enough to overwrite all the progress information we have sent, add some
    # more spaces.
    if final and self._update_len:
      print(' ' * self._update_len, '\r', end='')

    self._pending_nl = -1

  def _CheckStreamAndColor(self, stream, display):
    """Check that we're writing to the same stream as last call.  No?  New line.

    If starting a new line, set the color correctly:
      stdout  Magenta
      stderr  Red
      other   White / no colors

    Args:
      stream: The stream we're going to write to.
      display: True to display it on terms, False to suppress it.
    """
    if self._column > 0 and stream != self._cur_stream:
      self._FinishLine(display)
      if display:
        print(self._color.Stop())

      self._column = 0
      self._line = ''

    # Use colors for child output.
    if self._column == 0:
      self._FinishLine(display)
      if display:
        color = None
        if stream == sys.stdout:
          color = self._color.MAGENTA
        elif stream == sys.stderr:
          color = self._color.RED
        if color:
          sys.stdout.write(self._color.Start(color))

      self._cur_stream = stream

  def _Out(self, stream, text, display, newline=False, do_output_filter=True):
    """Output some text received from a child, or generated internally.

    This method is the guts of the Operation class since it understands how to
    convert a series of output requests on different streams into something
    coherent for the user.

    If the stream has changed, then a new line is started even if we were
    still halfway through the previous line. This prevents stdout and stderr
    becoming mixed up quite so badly.

    We use color to indicate lines which are stdout and stderr. If the output
    received from the child has color codes in it already, we pass these
    through, so our colors can be overridden. If output is redirected then we
    do not add color by default. Note that nothing stops the child from adding
    it, but since we present ourselves as a terminal to the child, one might
    hope that the child will not generate color.

    If display is False, then we will not actually send this text to the
    terminal. This is uses when verbose is required to be False.

    Args:
      stream: stream on which the text was received:
        sys.stdout    - received on stdout
        sys.stderr    - received on stderr
        None          - generated by us / internally
      text: text to output
      display: True to display it on terms, False to suppress it
      newline: True to start a new line after this text, False to put the next
        lot of output immediately after this.
      do_output_filter: True to look through output for errors and progress.
    """
    self._CheckStreamAndColor(stream, display)

    # Output what we have, and remember what column we are up to.
    if display:
      sys.stdout.write(text)
      self._column += len(text)
      # If a newline is required, remember to output it later.
      if newline:
        self._pending_nl = self._column
        self._column = 0

    self._line += text

    # If we now have a whole line, check it for errors and progress.
    if newline:
      if do_output_filter:
        self._FilterOutputForErrors(self._line, print_error=not display)
        self._FilterOutputForProgress(self._line)
      self._line = ''

  def Output(self, stream, data):
    r"""Handle the output of a block of text from the subprocess.

    All subprocess output should be sent through this method. It is split into
    lines which are processed separately using the _Out() method.

    Args:
      stream: Which file the output come in on:
        sys.stdout: stdout
        sys.stderr: stderr
        None: Our own internal output
      data: Output data as a big string, potentially containing many lines of
        text. Each line should end with \r\n. There is no requirement to send
        whole lines - this method happily handles fragments and tries to
        present then to the user as early as possible

    #TODO(sjg): Just use a list as the input parameter to avoid the split.
    """
    # We cannot use splitlines() here as we need this exact behavior
    lines = data.split('\r\n')

    # Output each full line, with a \n after it.
    for line in lines[:-1]:
      self._Out(stream, line, display=self.verbose, newline=True)

    # If we have a partial line at the end, output what we have.
    # We will continue it later.
    if lines[-1]:
      self._Out(stream, lines[-1], display=self.verbose)

    # Flush so that the terminal will receive partial line output (now!)
    sys.stdout.flush()

  def Outline(self, line):
    r"""Output a line of text to the display.

    This outputs text generated internally, such as a warning message or error
    summary. It ensures that our message plays nicely with child output if
    any.

    Args:
      line: text to output (without \n on the end)
    """
    self._Out(None, line, display=True, newline=True)
    self._FinishLine(display=True)

  def Info(self, line):
    r"""Output a line of information text to the display in verbose mode.

    Args:
      line: text to output (without \n on the end)
    """
    self._Out(None, self._color.Color(self._color.BLUE, line),
              display=self.verbose, newline=True, do_output_filter=False)
    self._FinishLine(display=True)

  def Notice(self, line):
    r"""Output a line of notification text to the display.

    Args:
      line: text to output (without \n on the end)
    """
    self._Out(None, self._color.Color(self._color.GREEN, line),
              display=True, newline=True, do_output_filter=False)
    self._FinishLine(display=True)

  def Warning(self, line):
    r"""Output a line of warning text to the display.

    Args:
      line: text to output (without \n on the end)
    """
    self._Out(None, self._color.Color(self._color.YELLOW, line),
              display=True, newline=True, do_output_filter=False)
    self._FinishLine(display=True)

  def Error(self, line):
    r"""Output a line of error text to the display.

    Args:
      line: text to output (without \n on the end)
    """
    self._Out(None, self._color.Color(self._color.RED, line),
              display=True, newline=True, do_output_filter=False)
    self._FinishLine(display=True)

  def Die(self, line):
    r"""Output a line of error text to the display and die.

    Args:
      line: text to output (without \n on the end)
    """
    self.Error(line)
    sys.exit(1)

  @contextlib.contextmanager
  def RequestVerbose(self, request):
    """Perform something in verbose mode if the user hasn't disallowed it

    This is intended to be used with something like:

      with oper.RequestVerbose(True):
        ... do some things that generate output

    Args:
      request: True to request verbose mode if available, False to do nothing.
    """
    old_verbose = self.verbose
    if request and not self.explicit_verbose:
      self.verbose = True
    try:
      yield
    finally:
      self.verbose = old_verbose
