# Copyright 2019 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Contains a threaded web server used for web platform tests."""

import os
import sys
import threading
import time
import uuid

SRC_DIR = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)
WPT_DIR = os.path.join(SRC_DIR, 'third_party', 'web_platform_tests')
sys.path.insert(0, WPT_DIR)

# pylint: disable=g-import-not-at-top
from tools.serve import serve
from tools.wptserve.wptserve import stash


class WebPlatformTestServer(object):
  """Runs a WPT StashServer on its own thread in a Python context manager."""

  def __init__(self, binding_address=None, wpt_http_port=None):
    # IP config['host'] should map to either through a dns or the hosts file.
    if binding_address:
      self._binding_address = binding_address
    else:
      self._binding_address = '127.0.0.1'
    if wpt_http_port:
      self._wpt_http_port = wpt_http_port
    else:
      self._wpt_http_port = '8000'

  def main(self):
    kwargs = vars(serve.get_parser().parse_args())

    # Configuration script to setup server used for serving web platform tests.
    config = serve.load_config(os.path.join(WPT_DIR, 'config.default.json'),
                               os.path.join(WPT_DIR, 'config.json'),
                               **kwargs)
    config['ports']['http'][0] = int(self._wpt_http_port)

    serve.setup_logger(config['log_level'])

    with stash.StashServer((self._binding_address, serve.get_port()),
                           authkey=str(uuid.uuid4())):
      with serve.get_ssl_environment(config) as ssl_env:
        _, self._servers = serve.start(config, ssl_env,
                                       serve.default_routes(), **kwargs)
        self._server_started = True

        try:
          while any(item.is_alive()
                    for item in serve.iter_procs(self._servers)):
            for item in serve.iter_procs(self._servers):
              item.join(1)
        except KeyboardInterrupt:
          serve.logger.info('Shutting down')

  def __enter__(self):
    self._server_started = False
    self._server_thread = threading.Thread(target=self.main)
    self._server_thread.start()
    while not self._server_started:
      time.sleep(.1)
    return self

  def __exit__(self, exc_type, exc_value, traceback):
    for _, servers in self._servers.iteritems():
      for _, server in servers:
        server.kill()
    self._server_thread.join()
