#!/usr/bin/python

# Copyright (c) 2017, Ximin Luo <infinity0@debian.org>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

from __future__ import print_function

import argparse
import json
import os
import shlex
import subprocess
import sys

self_script = "dh_webext"

app_packages_debian = {
    "gecko": [
        "firefox",
        #"thunderbird", thunderbird does not support webext yet
    ],
    "chromium": ["chromium"],
}

app_extension_paths = {
    "gecko": [
        "/usr/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
        #"/usr/share/mozilla/extensions/{3550f703-e582-4d05-9a08-453d09bdfdc6}", thunderbird does not support webext yet
    ],
    "chromium": ["/usr/share/chromium/extensions"],
}

def log(*args):
    print(self_script + ":", *args)

def run(cmdline, verbose=False):
    if verbose:
        print("  ", " ".join(shlex.quote(a) for a in cmdline))
    subprocess.check_call(cmdline)

def get_all_packages():
    lines = open("debian/control").readlines()
    package_lines = [x for x in lines if x.find("Package:") >= 0]
    packages = [p[p.find(":")+1:].strip() for p in package_lines]
    return packages

def generate_substvars(package, name, supported, verbose=False):
    ext_name = name
    for prefix in ("webext-",):
        if ext_name.startswith(prefix):
            ext_name = ext_name[len(prefix):]

    filename = "debian/%s.substvars" % package
    # TODO: read old file and merge the new values in

    lines = []
    debian_apps = sorted(set(deb for app in supported
        for deb in app_packages_debian[app]))

    # TODO: depends, recommends, breaks

    enhances = debian_apps
    lines.append("webext:Enhances=" + ", ".join(enhances) + "\n")

    provided = [prefix + "-" + ext_name for prefix in debian_apps]
    lines.append("webext:Provides=" + ", ".join(provided) + "\n")

    with open(filename, 'w+') as fp:
        fp.writelines(lines)

def install_for_app(extname, appname, appextname, supported, verbose=False):
    for p in app_extension_paths[appname]:
        run(["dh_link", "/usr/share/webext/%s" % extname,
            os.path.join(p, appextname)], verbose=verbose)
    supported.append(appname)

def install_webext(*args):
    parser = argparse.ArgumentParser(
        description="Debhelper command to install an unpacked WebExtension")
    parser.add_argument(
        "-p", "--package", dest="packages", metavar="PACKAGE", action="append", default=[],
        help="calculate substvars only for the specified PACKAGE")
    parser.add_argument(
        "-v", "--verbose", action="store_true", dest="verbose", default=False,
        help="print more information")
    parser.add_argument(
        'home', metavar='PATH', default='.',
        help='Path to the main directory. (Default: %(default)s)')
    parser.add_argument(
        'name', metavar='NAME', nargs='?', default=None,
        help='Short name of the extension.')
    # TODO: need to handle/ignore other debhelper options, see dh_xul-ext
    # for an example and `man debhelper` "COMMON DEBHELPER OPTIONS" for full list
    # TODO: import any useful options like -x from install-xpi
    args = parser.parse_args(args)
    args.packages = args.packages or get_all_packages()

    home = args.home
    name = args.name
    manifest = os.path.join(home, "manifest.json")
    if not os.path.exists(manifest):
        raise ValueError("does not exist: %s" % manifest)

    with open(manifest) as fp:
        manifest = json.load(fp)

        if name is None:
            name = manifest["name"]
        if name.startswith("_"):
            raise ValueError("name in manifest.json starts with _, please give actual name to %s" % self_script)

        run(["dh_install", "-X.git", "-Xdebian", home,
             "usr/share/webext/%s" % name], verbose=args.verbose)

        supported = []

        for appname, details in manifest["applications"].items():
            if appname in app_extension_paths:
                install_for_app(name, appname, details["id"], supported, args.verbose)
            else:
                log("unrecognised application in manifest: %s", appname)

        if "minimum_chrome_version" in manifest:
            install_for_app(name, "chromium", name, supported, args.verbose)

        if os.path.exists("debian/install-webext"):
            with open("debian/install-webext") as install_fp:
                for line in install_fp.readlines():
                    line = line.rstrip("\n")
                    if " " in line:
                        appname, extid = line.split(" ")
                    else:
                        appname, extid = line, name
                    install_for_app(name, appname, extid, supported, args.verbose)

        for package in args.packages:
            generate_substvars(package, name, supported, args.verbose)

        return 0
    return 1

if __name__ == '__main__':
    sys.exit(install_webext(*sys.argv[1:]))
