#!/usr/bin/env python
# Copyright (c) 2012 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.

"""Setups a local Rietveld instance to test against a live server for
integration tests.

It makes sure Google AppEngine SDK is found, download Rietveld and Django code
if necessary and starts the server on a free inbound TCP port.
"""

import logging
import optparse
import os
import shutil
import socket
import sys
import tempfile
import time

try:
  import subprocess2
except ImportError:
  sys.path.append(
      os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
  import subprocess2


class Failure(Exception):
  pass


def test_port(port):
  s = socket.socket()
  try:
    return s.connect_ex(('127.0.0.1', port)) == 0
  finally:
    s.close()


def find_free_port(start_port):
  """Search for a free port starting at specified port."""
  for port in xrange(start_port, (2<<16)):
    if not test_port(port):
      return port
  raise Failure('Having issues finding an available port')


class LocalRietveld(object):
  """Downloads everything needed to run a local instance of Rietveld."""

  def __init__(self, base_dir=None):
    # Paths
    self.base_dir = base_dir
    if not self.base_dir:
      self.base_dir = os.path.dirname(os.path.abspath(__file__))
    # TODO(maruel): This should be in /tmp but that would mean having to fetch
    # everytime. This test is already annoyingly slow.
    self.rietveld = os.path.join(self.base_dir, '_rietveld')
    self.rietveld_app = os.path.join(
        self.rietveld, 'appengine', 'chromium_rietveld')
    self.test_server = None
    self.port = None
    self.tempdir = None

    # Find the GAE SDK
    previous_dir = ''
    self.sdk_path = ''
    base_dir = self.base_dir
    while base_dir != previous_dir:
      previous_dir = base_dir
      self.sdk_path = os.path.join(base_dir, 'google_appengine')
      if not os.path.isfile(os.path.join(self.sdk_path, 'VERSION')):
        base_dir = os.path.dirname(base_dir)
    self.dev_app = os.path.join(self.sdk_path, 'dev_appserver.py')

  def install_prerequisites(self):
    # First, verify the Google AppEngine SDK is available.
    if not os.path.isfile(self.dev_app):
      raise Failure(
          'Install google_appengine sdk in %s or higher up' % self.base_dir)

    if os.path.isdir(os.path.join(self.rietveld, '.hg')):
      # Left over from mercurial. Delete it.
      print('Deleting deprecated mercurial rietveld files...')
      shutil.rmtree(self.rietveld)

    # Second, checkout rietveld if not available.
    if not os.path.isdir(self.rietveld):
      print('Checking out rietveld...')
      try:
        subprocess2.check_call(['git', 'init', self.rietveld])
        subprocess2.check_call(
            ['git', 'remote', 'add', '-f', 'origin',
             'https://chromium.googlesource.com/infra/infra.git'],
            cwd=self.rietveld)
        subprocess2.check_call(
            ['git', 'config', 'core.sparseCheckout', 'true'],
            cwd=self.rietveld)
        with file(os.path.join(self.rietveld, '.git/info/sparse-checkout'),
                  'w') as sparse_file:
          sparse_file.write('appengine/chromium_rietveld')
        subprocess2.check_call(
            ['git', 'pull', 'origin', 'master'],
            cwd=self.rietveld)
      except (OSError, subprocess2.CalledProcessError), e:
        raise Failure('Failed to clone rietveld. \n%s' % e)
    else:
      print('Syncing rietveld...')
      try:
        subprocess2.check_call(
            ['git', 'pull', 'origin', 'master'],
            cwd=self.rietveld)
      except (OSError, subprocess2.CalledProcessError), e:
        raise Failure('Failed to sync rietveld\n%s' % e)

  def start_server(self, verbose=False):
    self.install_prerequisites()
    assert not self.tempdir
    self.tempdir = tempfile.mkdtemp(prefix='rietveld_test')
    self.port = find_free_port(10000)
    admin_port = find_free_port(self.port + 1)
    if verbose:
      stdout = stderr = None
    else:
      stdout = subprocess2.PIPE
      stderr = subprocess2.STDOUT
    cmd = [
        sys.executable,
        self.dev_app,
        './app.yaml',  # Explicitly specify file to avoid bringing up backends.
        '--port', str(self.port),
        '--admin_port', str(admin_port),
        '--storage', self.tempdir,
        '--clear_search_indexes',
        '--skip_sdk_update_check',
    ]

    # CHEAP TRICK
    # By default you only want to bind on loopback but I'm testing over a
    # headless computer so it's useful to be able to access the test instance
    # remotely.
    if os.environ.get('GAE_LISTEN_ALL', '') == 'true':
      cmd.extend(('-a', '0.0.0.0'))
    logging.info(' '.join(cmd))
    self.test_server = subprocess2.Popen(
        cmd, stdout=stdout, stderr=stderr, cwd=self.rietveld_app)
    # Loop until port 127.0.0.1:port opens or the process dies.
    while not test_port(self.port):
      self.test_server.poll()
      if self.test_server.returncode is not None:
        if not verbose:
          out = self.test_server.communicate()[0]
        shutil.rmtree(self.tempdir)
        self.tempdir = None
        raise Failure(
            'Test rietveld instance failed early on port %s\n%s' %
              (self.port, out))
      time.sleep(0.01)

  def stop_server(self):
    if self.test_server:
      try:
        self.test_server.kill()
      except OSError:
        pass
      self.test_server.wait()
      self.test_server = None
      self.port = None
    if self.tempdir:
      shutil.rmtree(self.tempdir)
      self.tempdir = None


def main():
  parser = optparse.OptionParser()
  parser.add_option('-v', '--verbose', action='store_true')
  options, args = parser.parse_args()
  if args:
    parser.error('Unknown arguments: %s' % ' '.join(args))
  instance = LocalRietveld()
  try:
    instance.start_server(verbose=options.verbose)
    print 'Local rietveld instance started on port %d' % instance.port
    while True:
      time.sleep(0.1)
  finally:
    instance.stop_server()


if __name__ == '__main__':
  main()
