# 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 os
import threading
import sys
import time

import cros_build_lib as cros_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

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."""
  pass


class DevServerWrapper(threading.Thread):
  """A Simple wrapper around a dev server instance."""

  def __init__(self, test_root):
    self.proc = None
    self.test_root = test_root
    self._log_filename = os.path.join(test_root, 'dev_server.log')
    threading.Thread.__init__(self)

  def run(self):
    # Kill previous running instance of devserver if it exists.
    cros_lib.RunCommand(['sudo', 'pkill', '-f', 'devserver.py'], error_ok=True,
                        print_cmd=False)
    cros_lib.RunCommand(['sudo',
                         'start_devserver',
                         '--archive_dir=./static',
                         '--production',
                         ], enter_chroot=True, print_cmd=False,
                         log_to_file=self._log_filename,
                         cwd=cros_lib.GetCrosUtilsPath())

  def Stop(self):
    """Kills the devserver instance."""
    cros_lib.RunCommand(['sudo', 'pkill', '-f', 'devserver.py'], error_ok=True,
                        print_cmd=False)

  def PrintLog(self):
    """Print devserver output."""
    # Open in update mode in case the child process hasn't opened the file yet.
    log = open(self._log_filename, 'w+')
    print '--- Start output from %s ---' % self._log_filename
    for line in log:
      sys.stdout.write(line)
    print '--- End output from %s ---' % self._log_filename
    log.close()

  def WaitUntilStarted(self):
    """Wait until the devserver has started."""
    # Open in update mode in case the child process hasn't opened the file yet.
    log = open(self._log_filename, 'w+')
    pos = 0
    for _ in range(DEV_SERVER_TIMEOUT * 2):
      log.seek(pos)
      for line in log:
        # When the dev server has started, it will print a line stating
        # 'Bus STARTED'. Wait for that line to appear.
        if 'Bus STARTED' in line:
          log.close()
          return
        # If we've read a complete line, and it doesn't contain the magic
        # phrase, move on to the next line.
        if line.endswith('\n'):
          pos = log.tell()
      # Looks like it hasn't started yet. Keep waiting...
      time.sleep(0.5)
    else:
      log.close()
      self.PrintLog()
      raise DevServerException('Timeout waiting for the devserver to startup.')

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

  @classmethod
  def WipePayloadCache(cls):
    """Cleans up devserver cache of payloads."""
    cros_lib.Info('Cleaning up previously generated payloads.')
    cros_lib.RunCommandCaptureOutput(
        ['sudo', 'start_devserver', '--clear_cache', '--exit'],
        enter_chroot=True, print_cmd=False, combine_stdout_stderr=True,
        cwd=cros_lib.GetCrosUtilsPath())

