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

"""Module containing methods and classes to interact with a devserver instance.
"""

import logging
import multiprocessing
import os
import re
import sys
import tempfile
import time
import urllib2

import constants
from chromite.lib import cros_build_lib

# Wait up to 15 minutes for the dev server to start. It can take a while to
# start when generating payloads in parallel.
DEV_SERVER_TIMEOUT = 900
CHECK_HEALTH_URL = 'http://127.0.0.1:8080/check_health'
KILL_TIMEOUT = 10


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.
  """
  result = cros_build_lib.RunCommandCaptureOutput(
      ['/sbin/ifconfig', device], print_cmd=False)
  match = re.search('.*inet addr:(\d+\.\d+\.\d+\.\d+).*', result.output)
  if match:
    return match.group(1)
  cros_build_lib.Warning('Failed to find ip address in %r', result.output)
  return None


def GenerateUpdateId(target, src, key, for_vm):
  """Returns a simple representation id of target and src paths."""
  update_id = target
  if src: update_id = '->'.join([src, update_id])
  if key: update_id = '+'.join([update_id, key])
  if not for_vm: update_id = '+'.join([update_id, 'patched_kernel'])
  return update_id


class DevServerException(Exception):
  """Thrown when the devserver fails to start up correctly."""


class DevServerWrapper(multiprocessing.Process):
  """A Simple wrapper around a dev server instance."""

  def __init__(self, test_root=None):
    super(DevServerWrapper, self).__init__()
    self.test_root = test_root or DevServerWrapper.MkChrootTemp(is_dir=True)
    self._log_filename = os.path.join(self.test_root, 'dev_server.log')
    self._pid_file = DevServerWrapper.MkChrootTemp(is_dir=False)
    self._pid = None

  # Chroot helper methods. Since we call a script into the chroot with paths
  # created outside the chroot, translation back and forth is needed. These
  # methods all assume the default chroot dir.

  @staticmethod
  def MkChrootTemp(is_dir):
    """Returns a temp(dir if is_dir, file otherwise) in the chroot."""
    chroot_tmp = os.path.join(constants.SOURCE_ROOT, 'chroot', 'tmp')
    if is_dir:
      return tempfile.mkdtemp(prefix='devserver_wrapper', dir=chroot_tmp)
    else:
      return tempfile.NamedTemporaryFile(prefix='devserver_wrapper',
                                         dir=chroot_tmp, delete=False).name

  @staticmethod
  def ToChrootPath(path):
    """Converts the path outside the chroot to one that can be used inside."""
    path = os.path.abspath(path)
    if '/chroot/' not in path:
      raise ValueError('Path %s is not a path that points inside the chroot' %
                       path)

    return '/' + path.partition('/chroot/')[2]

  def _WaitUntilStarted(self):
    """Wait until the devserver has started."""
    current_time = time.time()
    deadline = current_time + DEV_SERVER_TIMEOUT
    while current_time <= deadline:
      try:
        if not self.is_alive():
          raise DevServerException('Devserver crashed while starting')

        urllib2.urlopen(CHECK_HEALTH_URL, timeout=0.05)
        return
      except IOError:
        # urlopen errors will throw a subclass of IOError if we can't connect.
        pass
      finally:
        # Let's not churn needlessly in this loop as the devserver starts up.
        time.sleep(1)

      current_time = time.time()
    else:
      self.terminate()
      raise DevServerException('Devserver did not start')

  def run(self):
    """Kicks off devserver in a separate process and waits for it to finish."""
    cmd = ['start_devserver',
           '--pidfile', DevServerWrapper.ToChrootPath(self._pid_file),
           '--logfile', DevServerWrapper.ToChrootPath(self._log_filename)]
    return_obj = cros_build_lib.SudoRunCommand(
        cmd, enter_chroot=True, debug_level=logging.DEBUG,
        cwd=constants.SOURCE_ROOT, error_code_ok=True,
        redirect_stdout=True, combine_stdout_stderr=True)
    if return_obj.returncode != 0:
      logging.error('Devserver terminated unexpectedly!')
      logging.error(return_obj.output)

  def Start(self):
    """Starts a background devserver and waits for it to start.

    Starts a background devserver and waits for it to start. Will only return
    once devserver has started and running pid has been read.
    """
    self.start()
    self._WaitUntilStarted()
    # Pid file was passed into the chroot.
    with open(self._pid_file, 'r') as f:
      self._pid = f.read()

  def Stop(self):
    """Kills the devserver instance with SIGTERM and SIGKILL if SIGTERM fails"""
    if not self._pid:
      logging.error('No devserver running.')
      return

    logging.debug('Stopping devserver instance with pid %s', self._pid)
    if self.is_alive():
      cros_build_lib.SudoRunCommand(['kill', self._pid],
                                    debug_level=logging.DEBUG)
    else:
      logging.error('Devserver not running!')
      return

    self.join(KILL_TIMEOUT)
    if self.is_alive():
      logging.warning('Devserver is unstoppable. Killing with SIGKILL')
      cros_build_lib.SudoRunCommand(['kill', '-9', self._pid],
                                    debug_level=logging.DEBUG)

  def PrintLog(self):
    """Print devserver output to stdout."""
    print '--- Start output from %s ---' % self._log_filename
    # Open in update mode in case the child process hasn't opened the file yet.
    with open(self._log_filename) as log:
      sys.stdout.writelines(log)

    print '--- End output from %s ---' % self._log_filename

  @classmethod
  def GetDevServerURL(cls, port=None, sub_dir=None):
    """Returns the dev server url for a given port and sub directory."""
    if not port: port = 8080
    url = 'http://%(ip)s:%(port)s' % {'ip': GetIPAddress(), 'port': str(port)}
    if sub_dir:
      url += '/' + sub_dir

    return url

  @classmethod
  def WipePayloadCache(cls):
    """Cleans up devserver cache of payloads."""
    cros_build_lib.Info('Cleaning up previously generated payloads.')
    cmd = ['start_devserver', '--clear_cache', '--exit']
    cros_build_lib.SudoRunCommand(
        cmd, enter_chroot=True, print_cmd=False, combine_stdout_stderr=True,
        redirect_stdout=True, redirect_stderr=True, cwd=constants.SOURCE_ROOT)
