# -*- coding: utf-8 -*-
# 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 division
from __future__ import print_function

import collections
import contextlib
import fcntl
import multiprocessing
import os
import pty
import re
import struct
import sys
import termios

from six.moves import queue as Queue

from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib.terminal import Color
from chromite.utils import outcap


# Define filenames for captured stdout and stderr.
STDOUT_FILE = 'stdout'
STDERR_FILE = 'stderr'

_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._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 outcap.OutputCapturer(
          stdout_path=self._stdout_path, stderr_path=self._stderr_path,
          quiet_fail=False):
        func(*args, **kwargs)
    finally:
      self._queue.put(_BackgroundTaskComplete())
      logging.getLogger().setLevel(restore_log_level)

  # 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.
      update_period: Optional argument to specify the period that output should
        be read.
      log_level: Logging level to run the func at. By default, it runs at log
        level info.
    """
    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:
      log_level = kwargs.pop('log_level', logging.INFO)
      restore_log_level = logging.getLogger().getEffectiveLevel()
      logging.getLogger().setLevel(log_level)
      try:
        func(*args, **kwargs)
      finally:
        logging.getLogger().setLevel(restore_log_level)
      return

    with osutils.TempDir() as tempdir:
      self._stdout_path = os.path.join(tempdir, STDOUT_FILE)
      self._stderr_path = os.path.join(tempdir, STDERR_FILE)
      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:
        # Add a blank line before the logging message so the message isn't
        # touching the progress bar.
        sys.stdout.write('\n')
        logging.error('Oops. Something went wrong.')
        # 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 = 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
