#!/usr/bin/python3
#
# Copyright (c) 2018 SUSE Linux GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 3 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact SUSE LLC.
#
# To contact SUSE about this file by physical or electronic mail,
# you may find current contact information at www.suse.com

"""
Generates a basic default XML configuration for docserv from
Git repositories.
"""

import os
import re
import sys
from xml.etree import cElementTree as etree


def generate_config(languages, branches, version="0.9.9", contact=None):
    """Generate the configuration file.

    :param language: The allowed languages
    :type languages: list

    :param branches:
    :type branches:

    :param str schemaversion: the schema version to use
    :param str contact: the contact email address
    """
    root = etree.Element("product", productid="FIXME", schemaversion=version)
    etree.SubElement(root, "name").text = "FIXME"
    etree.SubElement(root, "shortname").text = "FIXME"
    maintainers = etree.SubElement(root, "maintainers")
    etree.SubElement(maintainers, "contact").text = "FIXME" if not contact else contact

    for language in languages:
        description = etree.SubElement(root, "desc", default="0", lang=language)
        etree.SubElement(description, "p").text = "FIXME"

    for branch in branches:
        if branch.startswith("trans/"):
            continue
        docset = etree.SubElement(root, "docset", setid=branch.replace("maintenance/", ""), lifecycle="FIXME")
        etree.SubElement(docset, "version").text = "FIXME"
        builddocs = etree.SubElement(docset, "builddocs")
        git = etree.SubElement(builddocs, "git")
        etree.SubElement(git, "remote").text = "FIXME"
        for language in languages:
            if language == "en-us":
                lang = etree.SubElement(builddocs, "language", default="1", lang="en-us")
                etree.SubElement(lang, "branch").text = branch
                has_all_dc = "1"
                for dc_file in branches[branch]:
                    if "-all" in dc_file:
                        has_all_dc = "0"
                for dc_file in branches[branch]:
                    deliverable = etree.SubElement(lang, "deliverable")
                    etree.SubElement(deliverable, "dc", ).text = dc_file
                    dc_all_file = dc_file.endswith("-all")
                    attrs = {'pdf': "0" if dc_all_file else "1",
                             'epub': "0" if dc_all_file else "1",
                             'html': "1" if dc_all_file else has_all_dc,
                             'single-html': "0" if dc_all_file else "1",
                             }
                    etree.SubElement(deliverable, "format", **attrs)
            else:
                lang = etree.SubElement(builddocs, "language", lang=language)
                if branch.startswith("maintenance/") or branch.startswith("maint/"):
                    tmp = branch.replace("maintenance/", "").replace("maint/", "")
                    if "trans/%s" % tmp in branches:
                        branch = "trans/%s" % tmp
                etree.SubElement(lang, "branch").text = branch
                etree.SubElement(lang, "subdir").text = "FIXME"
                untrans = etree.SubElement(lang, "untranslated")
                deliverable = etree.SubElement(untrans, "deliverable")
                etree.SubElement(deliverable, "dc").text = "FIXME"
        extralinks = etree.SubElement(docset, "extralinks")
        etree.SubElement(extralinks, "link", href="FIXME").text = "SOME DESCRIPTION"
    tree = etree.ElementTree(root)
    configfile = os.getcwd() + "/config.xml"
    tree.write(configfile)
    print("Find the config file at {!r}".format(configfile))


def get_dc_files(path, branches, filter_dc=None):
    """Collect all DC files in branches.

    :param str path: the path to the Git repository
    :param dict branches: A dictionary with lists as keys like
         {'branch1': [], 'branch2': [], ...}
    :param filter_dc: filter
    :return: a dictionary with all DC files found in this branch
    :rtype: dict
    """
    repo = pygit2.Repository(path)
    tmp = branches
    for branch in list(branches):
        foo = repo.lookup_branch(branch)
        repo.checkout(foo)
        result = []
        for f in os.listdir(path):
            if os.path.isfile(os.path.join(path, f)):
                if filter_dc is not None:
                    if f.startswith("DC-") and filter_dc in f:
                        result.append(f)
                else:
                    if f.startswith("DC-"):
                        result.append(f)
        tmp[branch] = sorted(result)
    return tmp


def get_git_branches(path):
    """Return all the branches of a Git repository. Replace "origin/" with ""

    :param str path: the path to the Git repository
    :return: dictionary of all branches with their DC files, for example:
            {'develop': ['DC-foo', 'DC-foo-all'],
             'master':  ['DC-foo', 'DC-foo-all'],
             # ... more items pruned ...
             }
    :rtype: dict
    """
    repo = pygit2.Repository(path)
    result = {}
    for branch in sorted(repo.listall_branches(pygit2.GIT_BRANCH_ALL)):
        branch_wo_origin = branch.replace("origin/", "")
        if branch.startswith('maintenance/') or branch.startswith('trans/'):
            result[branch] = []
        elif branch_wo_origin == "develop" \
             or branch_wo_origin == "master" \
             or branch.startswith('origin/trans/') \
             or branch.startswith('origin/maintenance/'):
            result[branch_wo_origin] = []
    return result


def parse_cli(cliargs=None):
    """Parse CLI with :class:`argparse.ArgumentParser` and return parsed result.

    :param list cliargs: Arguments to parse or None (=use sys.argv)
    :return: parsed CLI result
    :rtype: :class:`argparse.Namespace`
    """
    import argparse

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("-l", "--languages",
                        help=("Uses one or more languages in the format "
                              "'language_country'. "
                              "Upper and lower case is irrelevant."
                              ),
                        )
    parser.add_argument("-f", "--filter",
                        help="Expects DC files which to focus on",
                        )
    parser.add_argument("-m", "--contact",
                        help="The contact email address",
                        )
    parser.add_argument("path",
                        metavar="PATH",
                        help="Path to the repository",
                        )
    args = parser.parse_args(args=cliargs)
    args.LANGUAGES = ("en-us de-de fr-fr pt-br ja-jp zh-cn es-es "
                      "it-it ko-kr hu-hu zh-tw cs-cz ar-ar pl-pl "
                      "ru-ru").split(" ")

    # do some checks:
    args.langs = set(args.languages.replace("_", "-").lower().split(" "))
    if not args.langs.intersection(args.LANGUAGES):
        parser.error("Unknown language {!r} found.\n"
                     "Expected one or more of these:\n"
                     "{}".format(args.languages, ", ".join(args.LANGUAGES))
                     )
    return args


if __name__ == "__main__":
    args = parse_cli()
    # print(args)

    import pygit2
    branches = get_git_branches(args.path)
    dc_files = get_dc_files(args.path, branches, filter_dc=args.filter)
    print(dc_files)
    generate_config(args.LANGUAGES, branches, contact=args.contact)
    sys.exit(0)
