# 1. install and setup mitmproxy v2.0.2: https://mitmproxy.readthedocs.io/en/v2.0.2/install.html
#   (In case of python versions trouble, use https://www.anaconda.com/)
# 2. mitmdump -q -s -p 8888 \
#   "serve-app-dev.py --app /path/to/polygerrit-ui/app/"
# 3. start Chrome with --proxy-server="127.0.0.1:8888" --user-data-dir=/tmp/devchrome
# 4. open, say, gerrit-review.googlesource.com. Or chromium-review.googlesource.com. Any.
# 5. uncompiled source files are served and you can log in, too.
# 6. enjoy!
#
# P.S. For replacing plugins, use --plugins or --plugin_root
#
# --plugin takes comma-separated list of plugins to add or replace.
#
# Example: Adding a new plugin to the server response:
# --plugins ~/gerrit-testsite/plugins/myplugin.html
#
# Example: Replace all matching plugins with local versions:
# --plugins ~/gerrit-testsite/plugins/
# Following files will be served if they exist for /plugins/tricium/static/tricium.html:
#  ~/gerrit-testsite/plugins/tricium.html
#  ~/gerrit-testsite/plugins/tricium/static/tricium.html
#
# --assets takes assets bundle.html, expecting rest of the assets files to be in the same folder
#
# Example:
#  --assets ~/gerrit-testsite/assets/a3be19f.html
#

from mitmproxy import http
from mitmproxy.script import concurrent
import argparse
import json
import mimetypes
import os.path
import re
import zipfile

class Server:
    def __init__(self, devpath, components, plugins, pluginroot, assets, strip_assets, theme):
        if devpath:
            print("Serving app from " + devpath)
        if components:
            print("Serving components from " + components)
        if pluginroot:
            print("Serving plugins from " + pluginroot)
        if assets:
            self.assets_root, self.assets_file = os.path.split(assets)
            print("Assets: using " + self.assets_file + " from " + self.assets_root)
        else:
            self.assets_root = None
        if plugins:
            self.plugins = {path.split("/")[-1:][0]: path for path in map(expandpath, plugins.split(","))}
            for filename, path in self.plugins.items():
                print("Serving " + filename + " from " + path)
        else:
            self.plugins = {}
        self.devpath = devpath
        self.components = components
        self.pluginroot = pluginroot
        self.strip_assets = strip_assets
        self.theme = theme

    def readfile(self, path):
        with open(path, 'rb') as contentfile:
            return contentfile.read()

@concurrent
def response(flow: http.HTTPFlow) -> None:
    if server.strip_assets:
        assets_bundle = 'googlesource.com/polygerrit_assets'
        assets_pos = flow.response.text.find(assets_bundle)
        if assets_pos != -1:
            t = flow.response.text
            flow.response.text = t[:t.rfind('<', 0, assets_pos)] + t[t.find('>', assets_pos) + 1:]
            return

    if server.assets_root:
        marker = 'webcomponents-lite.js"></script>'
        pos = flow.response.text.find(marker)
        if pos != -1:
            pos += len(marker)
            flow.response.text = ''.join([
                flow.response.text[:pos],
                '<link rel="import" href="/gerrit_assets/123.0/' + server.assets_file + '">',
                flow.response.text[pos:]
            ])

        assets_prefix = "/gerrit_assets/123.0/"
        if flow.request.path.startswith(assets_prefix):
            assets_file = flow.request.path[len(assets_prefix):]
            flow.response.content = server.readfile(server.assets_root + '/' + assets_file)
            flow.response.status_code = 200
            if assets_file.endswith('.js'):
                flow.response.headers['Content-type'] = 'text/javascript'
            return
    m = re.match(".+polygerrit_ui/\d+\.\d+/(.+)", flow.request.path)
    pluginmatch = re.match("^/plugins/(.+)", flow.request.path)
    localfile = ""
    content = ""
    if flow.request.path == "/config/server/info":
        config = json.loads(flow.response.content[5:].decode('utf8'))
        if server.theme:
            config['default_theme'] = '/static/gerrit-theme.html'
        for filename, path in server.plugins.items():
            pluginname = filename.split(".")[0]
            payload = config["plugin"]["js_resource_paths" if filename.endswith(".js") else "html_resource_paths"]
            if list(filter(lambda url: filename in url, payload)):
                continue
            payload.append("plugins/" + pluginname + "/static/" + filename)
        flow.response.content = str.encode(")]}'\n" + json.dumps(config))
    if m is not None:
        filepath = m.groups()[0]
        if (filepath.startswith("bower_components/")):
            with zipfile.ZipFile(server.components + "test_components.zip") as bower_zip:
                content = bower_zip.read(filepath)
        localfile = server.devpath + filepath
    elif pluginmatch is not None:
        pluginfile = flow.request.path_components[-1]
        if server.plugins and pluginfile in server.plugins:
            if os.path.isfile(server.plugins[pluginfile]):
                localfile = server.plugins[pluginfile]
            else:
                print("Can't find file " + server.plugins[pluginfile] + " for " + flow.request.path)
        elif server.pluginroot:
            pluginurl = pluginmatch.groups()[0]
            if os.path.isfile(server.pluginroot + pluginfile):
                localfile = server.pluginroot + pluginfile
            elif os.path.isfile(server.pluginroot + pluginurl):
                localfile = server.pluginroot + pluginurl

    if server.theme:
        if flow.request.path.endswith('/gerrit-theme.html'):
            localfile = server.theme
        else:
            match = re.match("^/static(/[\w\.]+)$", flow.request.path)
            if match is not None:
                localfile = os.path.dirname(server.theme) + match.group(1)

    if localfile and os.path.isfile(localfile):
        if pluginmatch is not None:
            print("Serving " + flow.request.path + " from " + localfile)
        content = server.readfile(localfile)

    if content:
        flow.response.content = content
        flow.response.status_code = 200
        localtype = mimetypes.guess_type(localfile)
        if localtype and localtype[0]:
            flow.response.headers['Content-type'] = localtype[0]

def expandpath(path):
    return os.path.realpath(os.path.expanduser(path))

parser = argparse.ArgumentParser()
parser.add_argument("--app", type=str, default="", help="Path to /polygerrit-ui/app/")
parser.add_argument("--components", type=str, default="", help="Path to test_components.zip")
parser.add_argument("--plugins", type=str, default="", help="Comma-separated list of plugin files to add/replace")
parser.add_argument("--plugin_root", type=str, default="", help="Path containing individual plugin files to replace")
parser.add_argument("--assets", type=str, default="", help="Path containing assets file to import.")
parser.add_argument("--strip_assets", action="store_true", help="Strip plugin bundles from the response.")
parser.add_argument("--theme", default="", type=str, help="Path to the default site theme to be used.")
args = parser.parse_args()
server = Server(expandpath(args.app) + '/',
                expandpath(args.components) + '/',
                args.plugins,
                expandpath(args.plugin_root) + '/',
                args.assets and expandpath(args.assets),
                args.strip_assets,
                expandpath(args.theme))
