#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import os
import subprocess
import time
import sys

import mopy.paths

from shutil import copyfileobj, rmtree
from signal import SIGTERM
from tempfile import mkdtemp, TemporaryFile


class TimeoutError(Exception):
  """Allows distinction between timeout failures and generic OSErrors."""
  pass


def _poll_for_condition(
    condition, max_seconds=10, sleep_interval=0.1, desc='[unnamed condition]'):
  """Poll until a condition becomes true.

  Arguments:
    condition: callable taking no args and returning bool.
    max_seconds: maximum number of seconds to wait.
                 Might bail up to sleep_interval seconds early.
    sleep_interval: number of seconds to sleep between polls.
    desc: description put in TimeoutError.

  Returns:
    The true value that caused the poll loop to terminate.

  Raises:
    TimeoutError if condition doesn't become true before max_seconds is reached.
  """
  start_time = time.time()
  while time.time() + sleep_interval - start_time <= max_seconds:
    value = condition()
    if value:
      return value
    time.sleep(sleep_interval)

  raise TimeoutError('Timed out waiting for condition: %s' % desc)


class _BackgroundShell(object):
  """Manages a mojo_shell instance that listens for external applications."""

  def __init__(self, mojo_shell_path, shell_args=None):
    """In a background process, run a shell at mojo_shell_path listening
    for external apps on an instance-specific socket.

    Arguments:
      mojo_shell_path: path to the mojo_shell binary to run.
      shell_args: a list of arguments to pass to mojo_shell.

    Raises:
      a TimeoutError if the shell takes too long to create the socket.
    """
    self._tempdir = mkdtemp(prefix='background_shell_')
    self._socket_path = os.path.join(self._tempdir, 'socket')
    self._output_file = TemporaryFile()

    shell_command = [mojo_shell_path,
                     '--enable-external-applications=' + self._socket_path]
    if shell_args:
      shell_command += shell_args
    logging.getLogger().debug(shell_command)

    self._shell = subprocess.Popen(shell_command, stdout=self._output_file,
                                   stderr=subprocess.STDOUT)
    _poll_for_condition(lambda: os.path.exists(self._socket_path),
                        desc="External app socket creation.")


  def __del__(self):
    if self._shell:
      self._shell.terminate()
      self._shell.wait()
      if self._shell.returncode != -SIGTERM:
        copyfileobj(self._output_file, sys.stdout)
    rmtree(self._tempdir)


  @property
  def socket_path(self):
    """The path of the socket where the shell is listening for external apps."""
    return self._socket_path


class BackgroundAppGroup(object):
  """Manages a group of mojo apps running in the background."""

  def __init__(self, paths, app_urls, shell_args=None):
    """In a background process, spins up mojo_shell with external
    applications enabled, passing an optional list of extra arguments.
    Then, launches apps indicated by app_urls in the background.
    The apps and shell are automatically torn down upon destruction.

    Arguments:
      paths: a mopy.paths.Paths object.
      app_urls: a list of URLs for apps to run via mojo_launcher.
      shell_args: a list of arguments to pass to mojo_shell.

    Raises:
      a TimeoutError if the shell takes too long to begin running.
    """
    self._shell = _BackgroundShell(paths.mojo_shell_path, shell_args)

    # Run apps defined by app_urls in the background.
    self._apps = []
    for app_url in app_urls:
      launch_command = [
          paths.mojo_launcher_path,
          '--shell-path=' + self._shell.socket_path,
          '--app-url=' + app_url,
          '--app-path=' + paths.FileFromUrl(app_url),
          '--vmodule=*/mojo/shell/*=2']
      logging.getLogger().debug(launch_command)
      app_output_file = TemporaryFile()
      self._apps.append((app_output_file,
                         subprocess.Popen(launch_command,
                                          stdout=app_output_file,
                                          stderr=subprocess.STDOUT)))


  def __del__(self):
    self._StopApps()


  def __enter__(self):
    return self


  def __exit__(self, ex_type, ex_value, traceback):
    self._StopApps()


  def _StopApps(self):
    """Terminate all background apps."""
    for output_file, app in self._apps:
      app.terminate()
      app.wait()
      if app.returncode != -SIGTERM:
        copyfileobj(output_file, sys.stdout)
    self._apps = []


  @property
  def socket_path(self):
    """The path of the socket where the shell is listening for external apps."""
    return self._shell._socket_path
