# 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
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)
import threading
import time
import uuid

from tools.serve import serve
from tools.wptserve.wptserve import stash


class WebPlatformTestServer(object):

  def __init__(self, binding_address=None):
    # IP that 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'

  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)

    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:
        config_, 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 scheme, servers in self._servers.iteritems():
      for port, server in servers:
        server.kill()
    self._server_thread.join()
