# -*- coding: utf-8 -*-
# Copyright 2010-2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""A utility tool to run NaCl Pepper HTTPClient test.

Example usage:
  The following command starts HTTP server and launch Chrome with the extension
  and open test.html. When '/TEST_FIN?result=success' is accessed from the page
  or the extension, this command successfully exit.
  When '/TEST_FIN?result=SOME_ERROR' is accessed, it exit showing SOME_ERROR.
  When the timeout specified has expired, it exit showing timeout error.

  python nacl_net_test_server.py --browser_path=/usr/bin/google-chrome \
    --serving_dir=/PATH/TO/FILE_DIR \
    --serving_dir=/PATH/TO/ADDITIONAL_FILE_DIR \
    --load_extension=/PATH/TO/EXTENSION_DIR \
    --url=test.html \
    --timeout=20
"""

import BaseHTTPServer
import optparse
import os
import os.path
import shutil
import SocketServer
import subprocess
import sys
import tempfile
import thread
import time
import urlparse


class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  """Handle the HTTP requests that arrive at the server."""

  def do_GET(self):
  # pylint: disable=g-bad-name
    """Handles GET request."""
    parsed_path = urlparse.urlparse(self.path)
    options = {'response': 200,
               'result': '',
               'before_response_sleep': 0.0,
               'before_head_sleep': 0.0,
               'after_head_sleep': 0.0,
               'before_data_sleep': 0.0,
               'after_data_sleep': 0.0,
               'content_length': '',
               'data': 'DEFAULT_DATA',
               'times': 1,
               'redirect_location': ''}
    query = urlparse.parse_qsl(parsed_path.query)
    for params in query:
      options[params[0]] = params[1]

    if parsed_path.path.startswith('/TEST_FIN'):
      if 'result' in options:
        if options['result'] == 'success':
          self.server.result = 0
        else:
          self.server.result = options['result']
      self.server.finished = True
      return

    # For retry test.
    if parsed_path.path.startswith('/RETRY_TEST'):
      if 'action' in options:
        self.send_response(200)
        self.end_headers()
        if options['action'] == 'set_counter':
          self.wfile.write('OK')
          self.server.retry_test_counter = int(options['value'])
        elif options['action'] == 'get_counter':
          self.wfile.write(str(self.server.retry_test_counter))
        return
      else:
        self.server.retry_test_counter += 1
        if self.server.retry_test_counter <= 0:
          self.send_response(404)
          self.end_headers()
          self.wfile.write('NG')
          return

    for extra_dir in self.server.serving_dirs:
      full_path = os.path.join(extra_dir, os.path.basename(parsed_path.path))
      if os.path.isfile(full_path):
        try:
          data = open(full_path).read()
          self.send_response(200)
          self.send_header('Content-Length', len(data))
          self.end_headers()
          self.wfile.write(data)
        except IOError, (errno, strerror):
          print 'I/O error(%s): %s' % (errno, strerror)
        return

    try:
      time.sleep(float(options['before_response_sleep']))
      self.send_response(int(options['response']))
      time.sleep(float(options['before_head_sleep']))
      self.send_header('command', '%s' % self.command)
      self.send_header('path', '%s' % self.path)
      self.send_header('parsed_path', '%s' % parsed_path.path)
      for name, value in sorted(self.headers.items()):
        self.send_header('CLIENT_HEADER_%s' % name, '%s' % value)
      if options['content_length']:
        self.send_header('Content-Length',
                         options['content_length'])
      if options['redirect_location']:
        self.send_header('Location',
                         options['redirect_location'])
      self.end_headers()
      time.sleep(float(options['after_head_sleep']))
      for _ in range(int(options['times'])):
        time.sleep(float(options['before_data_sleep']))
        self.wfile.write(options['data'])
        time.sleep(float(options['after_data_sleep']))
    except IOError, (errno, strerror):
      print 'I/O error(%s): %s' % (errno, strerror)
    return

  def do_POST(self):
  # pylint: disable=g-bad-name
    """Handles POST request."""
    parsed_path = urlparse.urlparse(self.path)
    options = {'response': 200,
               'result': '',
               'before_response_sleep': 0.0,
               'before_head_sleep': 0.0,
               'after_head_sleep': 0.0,
               'after_data_sleep': 0.0,
               'content_length': '',
               'redirect_location': ''}
    query = urlparse.parse_qsl(parsed_path.query)
    for params in query:
      options[params[0]] = params[1]

    try:
      content_len = int(self.headers.getheader('content-length'))
      post_data = self.rfile.read(content_len)
      time.sleep(float(options['before_response_sleep']))
      self.send_response(int(options['response']))
      time.sleep(float(options['before_head_sleep']))
      self.send_header('command', '%s' % self.command)
      self.send_header('path', '%s' % self.path)
      self.send_header('parsed_path', '%s' % parsed_path.path)
      for name, value in sorted(self.headers.items()):
        self.send_header('CLIENT_HEADER_%s' % name, '%s' % value)
      if options['content_length']:
        self.send_header('Content-Length',
                         options['content_length'])
      if options['redirect_location']:
        self.send_header('Location',
                         options['redirect_location'])
      self.end_headers()
      time.sleep(float(options['after_head_sleep']))
      self.wfile.write(post_data)
      time.sleep(float(options['after_data_sleep']))
      return
    except IOError, (errno, strerror):
      print 'I/O error(%s): %s' % (errno, strerror)
    return

  def do_HEAD(self):
  # pylint: disable=g-bad-name
    """Handles HEAD request."""
    parsed_path = urlparse.urlparse(self.path)
    options = {'response': 200,
               'before_response_sleep': 0.0,
               'before_head_sleep': 0.0}
    query = urlparse.parse_qsl(parsed_path.query)
    for params in query:
      options[params[0]] = params[1]

    try:
      time.sleep(float(options['before_response_sleep']))
      self.send_response(options['response'])
      time.sleep(float(options['before_head_sleep']))
      self.send_header('command', '%s' % self.command)
      self.send_header('path', '%s' % self.path)
      self.send_header('parsed_path', '%s' % parsed_path.path)
      for name, value in sorted(self.headers.items()):
        self.send_header('CLIENT_HEADER_%s' % name, '%s' % value)
      self.end_headers()
    except IOError, (errno, strerror):
      print 'I/O error(%s): %s' % (errno, strerror)
    return


class TestServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
  def Configure(self, serving_dirs):
    self.serving_dirs = serving_dirs
    self.finished = False
    self.result = 'Not Finished.'
    self.retry_test_counter = 0


def main():
  parser = optparse.OptionParser(usage='Usage: %prog [options]')
  parser.add_option('--timeout', dest='timeout', action='store', type='float',
                    default=5.0, help='Timeout in seconds.')
  parser.add_option('--browser_path', dest='browser_path', action='store',
                    type='string', default='/usr/bin/google-chrome',
                    help='The browser path.')
  parser.add_option('--serving_dir', dest='serving_dirs', action='append',
                    type='string', default=[],
                    help='File directory to be served by HTTP server.')
  parser.add_option('--load_extension', dest='load_extension', action='store',
                    type='string', default='', help='The extension path.')
  parser.add_option('-u', '--url', dest='url', action='store',
                    type='string', default=None, help='The webpage to load.')
  (options, _) = parser.parse_args()
  # TODO(horo) Don't use the fixed port number. Find the way to pass the port
  # number to the test module.
  server = TestServer(('localhost', 9999), RequestHandler)
  server.Configure(options.serving_dirs)
  host, port = server.socket.getsockname()
  print 'Starting server %s:%s' % (host, port)

  def Serve():
    while not server.finished:
      server.handle_request()
  thread.start_new_thread(Serve, ())

  temp_dir = tempfile.mkdtemp()
  if options.browser_path:
    cmd = [options.browser_path, '--user-data-dir=%s' % temp_dir]
    if options.load_extension:
      cmd.append('--load-extension=%s' % options.load_extension)
    if options.url:
      cmd.append('http://%s:%s/%s' % (host, port, options.url))
    print cmd
    browser_handle = subprocess.Popen(cmd)

  time_started = time.time()
  result = 0

  while True:
    if time.time() - time_started >= options.timeout:
      result = 'Timeout!: %s' %  (time.time() - time_started)
      break
    if server.finished:
      result = server.result
      break
    time.sleep(0.5)

  if options.browser_path:
    browser_handle.kill()
    browser_handle.wait()
  shutil.rmtree(temp_dir)
  sys.exit(result)

if __name__ == '__main__':
  main()
