# -*- coding: utf-8 -*-

from __future__ import print_function

import abc
import argparse
import json
import os
import re
import socket
import sys
import threading
import time
import traceback
from six.moves import urllib
import uuid
from collections import defaultdict, OrderedDict
from multiprocessing import Process, Event

from ..localpaths import repo_root

import sslutils
from manifest.sourcefile import read_script_metadata, js_meta_re
from wptserve import server as wptserve, handlers
from wptserve import stash
from wptserve.logger import set_logger
from wptserve.handlers import filesystem_path, wrap_pipeline
from mod_pywebsocket import standalone as pywebsocket

def replace_end(s, old, new):
    """
    Given a string `s` that ends with `old`, replace that occurrence of `old`
    with `new`.
    """
    assert s.endswith(old)
    return s[:-len(old)] + new


class WrapperHandler(object):

    __meta__ = abc.ABCMeta

    headers = []

    def __init__(self, base_path=None, url_base="/"):
        self.base_path = base_path
        self.url_base = url_base
        self.handler = handlers.handler(self.handle_request)

    def __call__(self, request, response):
        self.handler(request, response)

    def handle_request(self, request, response):
        for header_name, header_value in self.headers:
            response.headers.set(header_name, header_value)

        path = self._get_path(request.url_parts.path, True)
        meta = "\n".join(self._get_meta(request))
        response.content = self.wrapper % {"meta": meta, "path": path}
        wrap_pipeline(path, request, response)

    def _get_path(self, path, resource_path):
        """Convert the path from an incoming request into a path corresponding to an "unwrapped"
        resource e.g. the file on disk that will be loaded in the wrapper.

        :param path: Path from the HTTP request
        :param resource_path: Boolean used to control whether to get the path for the resource that
                              this wrapper will load or the associated file on disk.
                              Typically these are the same but may differ when there are multiple
                              layers of wrapping e.g. for a .any.worker.html input the underlying disk file is
                              .any.js but the top level html file loads a resource with a
                              .any.worker.js extension, which itself loads the .any.js file.
                              If True return the path to the resource that the wrapper will load,
                              otherwise return the path to the underlying file on disk."""
        for item in self.path_replace:
            if len(item) == 2:
                src, dest = item
            else:
                assert len(item) == 3
                src = item[0]
                dest = item[2 if resource_path else 1]
            if path.endswith(src):
                path = replace_end(path, src, dest)
        return path

    def _get_meta(self, request):
        """Get an iterator over strings to inject into the wrapper document
        based on //META comments in the associated js file.

        :param request: The Request being processed.
        """
        path = self._get_path(filesystem_path(self.base_path, request, self.url_base), False)
        with open(path, "rb") as f:
            for key, value in read_script_metadata(f, js_meta_re):
                replacement = self._meta_replacement(key, value)
                if replacement:
                    yield replacement

    @abc.abstractproperty
    def path_replace(self):
        # A list containing a mix of 2 item tuples with (input suffix, output suffix)
        # and 3-item tuples with (input suffix, filesystem suffix, resource suffix)
        # for the case where we want a different path in the generated resource to
        # the actual path on the filesystem (e.g. when there is another handler
        # that will wrap the file).
        return None

    @abc.abstractproperty
    def wrapper(self):
        # String template with variables path and meta for wrapper document
        return None

    @abc.abstractmethod
    def _meta_replacement(self, key, value):
        # Get the string to insert into the wrapper document, given
        # a specific metadata key: value pair.
        pass


class HtmlWrapperHandler(WrapperHandler):
    def _meta_replacement(self, key, value):
        if key == b"timeout":
            if value == b"long":
                return '<meta name="timeout" content="long">'
        if key == b"script":
            attribute = value.decode('utf-8').replace('"', "&quot;").replace(">", "&gt;")
            return '<script src="%s"></script>' % attribute
        return None


class WorkersHandler(HtmlWrapperHandler):
    path_replace = [(".any.worker.html", ".any.js", ".any.worker.js"),
                    (".worker.html", ".worker.js")]
    wrapper = """<!doctype html>
<meta charset=utf-8>
%(meta)s
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
fetch_tests_from_worker(new Worker("%(path)s"));
</script>
"""


class WindowHandler(HtmlWrapperHandler):
    path_replace = [(".window.html", ".window.js")]
    wrapper = """<!doctype html>
<meta charset=utf-8>
%(meta)s
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script src="%(path)s"></script>
"""


class AnyHtmlHandler(HtmlWrapperHandler):
    path_replace = [(".any.html", ".any.js")]
    wrapper = """<!doctype html>
<meta charset=utf-8>
%(meta)s
<script>
self.GLOBAL = {
  isWindow: function() { return true; },
  isWorker: function() { return false; },
};
</script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script src="%(path)s"></script>
"""


class AnyWorkerHandler(WrapperHandler):
    headers = [('Content-Type', 'text/javascript')]
    path_replace = [(".any.worker.js", ".any.js")]
    wrapper = """%(meta)s
self.GLOBAL = {
  isWindow: function() { return false; },
  isWorker: function() { return true; },
};
importScripts("/resources/testharness.js");
importScripts("%(path)s");
done();
"""

    def _meta_replacement(self, key, value):
        if key == b"timeout":
            return None
        if key == b"script":
            attribute = value.decode('utf-8').replace("\\", "\\\\").replace('"', '\\"')
            return 'importScripts("%s")' % attribute
        return None


rewrites = [("GET", "/resources/WebIDLParser.js", "/resources/webidl2/lib/webidl2.js")]

subdomains = [u"www",
              u"www1",
              u"www2",
              u"天気の良い日",
              u"élève"]

class RoutesBuilder(object):
    def __init__(self):
        self.forbidden_override = [("GET", "/tools/runner/*", handlers.file_handler),
                                   ("POST", "/tools/runner/update_manifest.py",
                                    handlers.python_script_handler)]

        self.forbidden = [("*", "/_certs/*", handlers.ErrorHandler(404)),
                          ("*", "/tools/*", handlers.ErrorHandler(404)),
                          ("*", "{spec}/tools/*", handlers.ErrorHandler(404)),
                          ("*", "/serve.py", handlers.ErrorHandler(404))]

        self.static = []

        self.mountpoint_routes = OrderedDict()

        self.add_mount_point("/", None)

    def get_routes(self):
        routes = self.forbidden_override + self.forbidden + self.static
        # Using reversed here means that mount points that are added later
        # get higher priority. This makes sense since / is typically added
        # first.
        for item in reversed(self.mountpoint_routes.values()):
            routes.extend(item)
        return routes

    def add_static(self, path, format_args, content_type, route):
        handler = handlers.StaticHandler(path, format_args, content_type)
        self.static.append((b"GET", str(route), handler))

    def add_mount_point(self, url_base, path):
        url_base = "/%s/" % url_base.strip("/") if url_base != "/" else "/"

        self.mountpoint_routes[url_base] = []

        routes = [
            ("GET", "*.worker.html", WorkersHandler),
            ("GET", "*.window.html", WindowHandler),
            ("GET", "*.any.html", AnyHtmlHandler),
            ("GET", "*.any.worker.js", AnyWorkerHandler),
            ("GET", "*.asis", handlers.AsIsHandler),
            ("*", "*.py", handlers.PythonScriptHandler),
            ("GET", "*", handlers.FileHandler)
        ]

        for (method, suffix, handler_cls) in routes:
            self.mountpoint_routes[url_base].append(
                (method,
                 "{}{}".format(str(url_base) if url_base != "/" else "", str(suffix)).encode(),
                 handler_cls(base_path=path, url_base=url_base)))

    def add_file_mount_point(self, file_url, base_path):
        assert file_url.startswith("/")
        url_base = file_url[0:file_url.rfind("/") + 1]
        self.mountpoint_routes[file_url] = [("GET", file_url, handlers.FileHandler(base_path=base_path, url_base=url_base))]


def build_routes(aliases):
    builder = RoutesBuilder()
    for alias in aliases:
        url = alias["url-path"]
        directory = alias["local-dir"]
        if not url.startswith("/") or len(directory) == 0:
            logger.error("\"url-path\" value must start with '/'.")
            continue
        if url.endswith("/"):
            builder.add_mount_point(url, directory)
        else:
            builder.add_file_mount_point(url, directory)
    return builder.get_routes()


def default_routes(**kwargs):
    config = load_config(os.path.join(repo_root, "config.default.json"),
                         os.path.join(repo_root, "config.json"),
                         **kwargs)
    return build_routes(config["aliases"])


def setup_logger(level):
    import logging
    global logger
    logger = logging.getLogger("web-platform-tests")
    logging.basicConfig(level=getattr(logging, level.upper()))
    set_logger(logger)


def open_socket(port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    if port != 0:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('127.0.0.1', port))
    sock.listen(5)
    return sock

def bad_port(port):
    """
    Bad port as per https://fetch.spec.whatwg.org/#port-blocking
    """
    return port in [
        1,     # tcpmux
        7,     # echo
        9,     # discard
        11,    # systat
        13,    # daytime
        15,    # netstat
        17,    # qotd
        19,    # chargen
        20,    # ftp-data
        21,    # ftp
        22,    # ssh
        23,    # telnet
        25,    # smtp
        37,    # time
        42,    # name
        43,    # nicname
        53,    # domain
        77,    # priv-rjs
        79,    # finger
        87,    # ttylink
        95,    # supdup
        101,   # hostriame
        102,   # iso-tsap
        103,   # gppitnp
        104,   # acr-nema
        109,   # pop2
        110,   # pop3
        111,   # sunrpc
        113,   # auth
        115,   # sftp
        117,   # uucp-path
        119,   # nntp
        123,   # ntp
        135,   # loc-srv / epmap
        139,   # netbios
        143,   # imap2
        179,   # bgp
        389,   # ldap
        465,   # smtp+ssl
        512,   # print / exec
        513,   # login
        514,   # shell
        515,   # printer
        526,   # tempo
        530,   # courier
        531,   # chat
        532,   # netnews
        540,   # uucp
        556,   # remotefs
        563,   # nntp+ssl
        587,   # smtp
        601,   # syslog-conn
        636,   # ldap+ssl
        993,   # imap+ssl
        995,   # pop3+ssl
        2049,  # nfs
        3659,  # apple-sasl
        4045,  # lockd
        6000,  # x11
        6665,  # irc (alternate)
        6666,  # irc (alternate)
        6667,  # irc (default)
        6668,  # irc (alternate)
        6669,  # irc (alternate)
    ]

def get_port():
    port = 0
    while True:
        free_socket = open_socket(0)
        port = free_socket.getsockname()[1]
        free_socket.close()
        if not bad_port(port):
            break
    logger.debug("Going to use port %s" % port)
    return port


class ServerProc(object):
    def __init__(self):
        self.proc = None
        self.daemon = None
        self.stop = Event()

    def start(self, init_func, host, port, paths, routes, bind_hostname, external_config,
              ssl_config, **kwargs):
        self.proc = Process(target=self.create_daemon,
                            args=(init_func, host, port, paths, routes, bind_hostname,
                                  external_config, ssl_config),
                            kwargs=kwargs)
        self.proc.daemon = True
        self.proc.start()

    def create_daemon(self, init_func, host, port, paths, routes, bind_hostname,
                      external_config, ssl_config, **kwargs):
        try:
            self.daemon = init_func(host, port, paths, routes, bind_hostname, external_config,
                                    ssl_config, **kwargs)
        except socket.error:
            print("Socket error on port %s" % port, file=sys.stderr)
            raise
        except:
            print(traceback.format_exc(), file=sys.stderr)
            raise

        if self.daemon:
            try:
                self.daemon.start(block=False)
                try:
                    self.stop.wait()
                except KeyboardInterrupt:
                    pass
            except:
                print(traceback.format_exc(), file=sys.stderr)
                raise

    def wait(self):
        self.stop.set()
        self.proc.join()

    def kill(self):
        self.stop.set()
        self.proc.terminate()
        self.proc.join()

    def is_alive(self):
        return self.proc.is_alive()


def check_subdomains(host, paths, bind_hostname, ssl_config, aliases):
    port = get_port()
    subdomains = get_subdomains(host)

    wrapper = ServerProc()
    wrapper.start(start_http_server, host, port, paths, build_routes(aliases), bind_hostname,
                  None, ssl_config)

    connected = False
    for i in range(10):
        try:
            urllib.request.urlopen("http://%s:%d/" % (host, port))
            connected = True
            break
        except urllib.error.URLError:
            time.sleep(1)

    if not connected:
        logger.critical("Failed to connect to test server on http://%s:%s You may need to edit /etc/hosts or similar" % (host, port))
        sys.exit(1)

    for subdomain, (punycode, host) in subdomains.items():
        domain = "%s.%s" % (punycode, host)
        try:
            urllib.request.urlopen("http://%s:%d/" % (domain, port))
        except Exception as e:
            logger.critical("Failed probing domain %s. You may need to edit /etc/hosts or similar." % domain)
            sys.exit(1)

    wrapper.wait()


def get_subdomains(host):
    #This assumes that the tld is ascii-only or already in punycode
    return {subdomain: (subdomain.encode("idna"), host.encode())
            for subdomain in subdomains}


def start_servers(host, ports, paths, routes, bind_hostname, external_config, ssl_config,
                  **kwargs):
    servers = defaultdict(list)
    for scheme, ports in ports.items():
        assert len(ports) == {"http":2}.get(scheme, 1)

        for port in ports:
            if port is None:
                continue
            init_func = {"http":start_http_server,
                         "https":start_https_server,
                         "ws":start_ws_server,
                         "wss":start_wss_server}[scheme]

            server_proc = ServerProc()
            server_proc.start(init_func, host, port, paths, routes, bind_hostname,
                              external_config, ssl_config, **kwargs)
            servers[scheme].append((port, server_proc))

    return servers


def start_http_server(host, port, paths, routes, bind_hostname, external_config, ssl_config,
                      **kwargs):
    return wptserve.WebTestHttpd(host=host,
                                 port=port,
                                 doc_root=paths["doc_root"],
                                 routes=routes,
                                 rewrites=rewrites,
                                 bind_hostname=bind_hostname,
                                 config=external_config,
                                 use_ssl=False,
                                 key_file=None,
                                 certificate=None,
                                 latency=kwargs.get("latency"))


def start_https_server(host, port, paths, routes, bind_hostname, external_config, ssl_config,
                       **kwargs):
    return wptserve.WebTestHttpd(host=host,
                                 port=port,
                                 doc_root=paths["doc_root"],
                                 routes=routes,
                                 rewrites=rewrites,
                                 bind_hostname=bind_hostname,
                                 config=external_config,
                                 use_ssl=True,
                                 key_file=ssl_config["key_path"],
                                 certificate=ssl_config["cert_path"],
                                 encrypt_after_connect=ssl_config["encrypt_after_connect"],
                                 latency=kwargs.get("latency"))


class WebSocketDaemon(object):
    def __init__(self, host, port, doc_root, handlers_root, log_level, bind_hostname,
                 ssl_config):
        self.host = host
        cmd_args = ["-p", port,
                    "-d", doc_root,
                    "-w", handlers_root,
                    "--log-level", log_level]

        if ssl_config is not None:
            # This is usually done through pywebsocket.main, however we're
            # working around that to get the server instance and manually
            # setup the wss server.
            if pywebsocket._import_ssl():
                tls_module = pywebsocket._TLS_BY_STANDARD_MODULE
            elif pywebsocket._import_pyopenssl():
                tls_module = pywebsocket._TLS_BY_PYOPENSSL
            else:
                print("No SSL module available")
                sys.exit(1)

            cmd_args += ["--tls",
                         "--private-key", ssl_config["key_path"],
                         "--certificate", ssl_config["cert_path"],
                         "--tls-module", tls_module]

        if (bind_hostname):
            cmd_args = ["-H", host] + cmd_args
        opts, args = pywebsocket._parse_args_and_config(cmd_args)
        opts.cgi_directories = []
        opts.is_executable_method = None
        self.server = pywebsocket.WebSocketServer(opts)
        ports = [item[0].getsockname()[1] for item in self.server._sockets]
        assert all(item == ports[0] for item in ports)
        self.port = ports[0]
        self.started = False
        self.server_thread = None

    def start(self, block=False):
        self.started = True
        if block:
            self.server.serve_forever()
        else:
            self.server_thread = threading.Thread(target=self.server.serve_forever)
            self.server_thread.setDaemon(True)  # don't hang on exit
            self.server_thread.start()

    def stop(self):
        """
        Stops the server.

        If the server is not running, this method has no effect.
        """
        if self.started:
            try:
                self.server.shutdown()
                self.server.server_close()
                self.server_thread.join()
                self.server_thread = None
            except AttributeError:
                pass
            self.started = False
        self.server = None


def start_ws_server(host, port, paths, routes, bind_hostname, external_config, ssl_config,
                    **kwargs):
    return WebSocketDaemon(host,
                           str(port),
                           repo_root,
                           paths["ws_doc_root"],
                           "debug",
                           bind_hostname,
                           ssl_config = None)


def start_wss_server(host, port, paths, routes, bind_hostname, external_config, ssl_config,
                     **kwargs):
    return WebSocketDaemon(host,
                           str(port),
                           repo_root,
                           paths["ws_doc_root"],
                           "debug",
                           bind_hostname,
                           ssl_config)


def get_ports(config, ssl_environment):
    rv = defaultdict(list)
    for scheme, ports in config["ports"].items():
        for i, port in enumerate(ports):
            if scheme in ["wss", "https"] and not ssl_environment.ssl_enabled:
                port = None
            if port == "auto":
                port = get_port()
            else:
                port = port
            rv[scheme].append(port)
    return rv



def normalise_config(config, ports):
    host = config["external_host"] if config["external_host"] else config["host"]
    domains = get_subdomains(host)
    ports_ = {}
    for scheme, ports_used in ports.items():
        ports_[scheme] = ports_used

    for key, value in domains.items():
        domains[key] = b".".join(value)

    domains[""] = host

    ports_ = {}
    for scheme, ports_used in ports.items():
        ports_[scheme] = ports_used

    return {"host": host,
            "domains": domains,
            "ports": ports_}


def get_ssl_config(config, external_domains, ssl_environment):
    key_path, cert_path = ssl_environment.host_cert_path(external_domains)
    return {"key_path": key_path,
            "cert_path": cert_path,
            "encrypt_after_connect": config["ssl"]["encrypt_after_connect"]}

def start(config, ssl_environment, routes, **kwargs):
    host = config["host"]
    domains = get_subdomains(host)
    ports = get_ports(config, ssl_environment)
    bind_hostname = config["bind_hostname"]

    paths = {"doc_root": config["doc_root"],
             "ws_doc_root": config["ws_doc_root"]}

    external_config = normalise_config(config, ports)

    ssl_config = get_ssl_config(config, external_config["domains"].values(), ssl_environment)

    if config["check_subdomains"]:
        check_subdomains(host, paths, bind_hostname, ssl_config, config["aliases"])

    servers = start_servers(host, ports, paths, routes, bind_hostname, external_config,
                            ssl_config, **kwargs)

    return external_config, servers


def iter_procs(servers):
    for servers in servers.values():
        for port, server in servers:
            yield server.proc


def value_set(config, key):
    return key in config and config[key] is not None


def get_value_or_default(config, key, default=None):
    return config[key] if value_set(config, key) else default


def set_computed_defaults(config):
    if not value_set(config, "doc_root"):
        config["doc_root"] = repo_root

    if not value_set(config, "ws_doc_root"):
        root = get_value_or_default(config, "doc_root", default=repo_root)
        config["ws_doc_root"] = os.path.join(root, "websockets", "handlers")

    if not value_set(config, "aliases"):
        config["aliases"] = []


def merge_json(base_obj, override_obj):
    rv = {}
    for key, value in base_obj.items():
        if key not in override_obj:
            rv[key] = value
        else:
            if isinstance(value, dict):
                rv[key] = merge_json(value, override_obj[key])
            else:
                rv[key] = override_obj[key]
    return rv


def get_ssl_environment(config):
    implementation_type = config["ssl"]["type"]
    cls = sslutils.environments[implementation_type]
    try:
        kwargs = config["ssl"][implementation_type].copy()
    except KeyError:
        raise ValueError("%s is not a vaid ssl type." % implementation_type)
    return cls(logger, **kwargs)


def load_config(default_path, override_path=None, **kwargs):
    if os.path.exists(default_path):
        with open(default_path) as f:
            base_obj = json.load(f)
    else:
        raise ValueError("Config path %s does not exist" % default_path)

    if os.path.exists(override_path):
        with open(override_path) as f:
            override_obj = json.load(f)
    else:
        override_obj = {}
    rv = merge_json(base_obj, override_obj)

    if kwargs.get("config_path"):
        other_path = os.path.abspath(os.path.expanduser(kwargs.get("config_path")))
        if os.path.exists(other_path):
            base_obj = rv
            with open(other_path) as f:
                override_obj = json.load(f)
            rv = merge_json(base_obj, override_obj)
        else:
            raise ValueError("Config path %s does not exist" % other_path)

    overriding_path_args = [("doc_root", "Document root"),
                            ("ws_doc_root", "WebSockets document root")]
    for key, title in overriding_path_args:
        value = kwargs.get(key)
        if value is None:
            continue
        value = os.path.abspath(os.path.expanduser(value))
        if not os.path.exists(value):
            raise ValueError("%s path %s does not exist" % (title, value))
        rv[key] = value

    set_computed_defaults(rv)
    return rv


def get_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument("--latency", type=int,
                        help="Artificial latency to add before sending http responses, in ms")
    parser.add_argument("--config", action="store", dest="config_path",
                        help="Path to external config file")
    parser.add_argument("--doc_root", action="store", dest="doc_root",
                        help="Path to document root. Overrides config.")
    parser.add_argument("--ws_doc_root", action="store", dest="ws_doc_root",
                        help="Path to WebSockets document root. Overrides config.")
    return parser


def run(**kwargs):
    config = load_config(os.path.join(repo_root, "config.default.json"),
                         os.path.join(repo_root, "config.json"),
                         **kwargs)

    setup_logger(config["log_level"])

    stash_address = None
    if config["bind_hostname"]:
        stash_address = (config["host"], get_port())

    with stash.StashServer(stash_address, authkey=str(uuid.uuid4())):
        with get_ssl_environment(config) as ssl_env:
            config_, servers = start(config, ssl_env, build_routes(config["aliases"]), **kwargs)

            try:
                while any(item.is_alive() for item in iter_procs(servers)):
                    for item in iter_procs(servers):
                        item.join(1)
            except KeyboardInterrupt:
                logger.info("Shutting down")


def main():
    kwargs = vars(get_parser().parse_args())
    return run(**kwargs)
