#!/usr/bin/python3

#
# Some notes to get this script up and running.
#
# To play around with this some more, try to:
#
# - create an empty translation:
#    cp po/ubuntu-packaging-guide.pot po/xx.po
# - run the script and see if it works and just takes the translations
#   above the threshold (PERCENTAGE variable)
# - make sure you don't accidentally commit changes to the packaging
#

from __future__ import print_function

import glob
import sys
import os

try:
    import polib
except ImportError:
    sys.exit("You need to have  python3-polib  installed.")

try:
    from debian import deb822
except ImportError:
    sys.exit("You need to have  python3-debian  installed.")

PERCENTAGE = 70


class Package(object):
    stanzas = None

    def __init__(self):
        # we assume, this file lives in "debian/scripts"
        self.script_path = os.path.dirname(__file__)
        self.base_path = os.path.join(self.script_path, "../..")
        self.po_path = os.path.join(self.base_path, "po/")
        self.control_file = os.path.join(self.base_path, "debian/control")
        self.makefile = os.path.join(self.base_path, "Makefile")
        self.language_names = {}
        self.all_pofiles = self.get_all_pofiles()
        self.all_languages = self.get_all_languages()
        self.semi_complete_pofiles = self.get_semi_complete_pofiles()
        self.semi_complete_languages = self.get_semi_complete_languages()
        self.available_binary_packages = self.get_available_binary_packages()
        self.available_binary_package_names = \
            self.get_available_binary_package_names()
        self.base_package_names = self.get_base_package_names()

    def fix_name(self, language_name):
        """Formats language names for use in package names, i.e.
        pt_BR -> pt-br."""
        return language_name.lower().replace('_', '-')

    def get_all_pofiles(self):
        return [os.path.abspath(a) for a in glob.glob("%s/*.po" % self.po_path)]

    def get_all_languages(self):
        return [os.path.basename(a).split(".po")[0] for a in self.all_pofiles]

    def get_semi_complete_pofiles(self):
        languages = self.all_pofiles
        for language in languages:
            pofile = polib.pofile(language)
            basename = os.path.basename(language)
            self.language_names[basename[:-3]] = pofile.header[:pofile.header.find(
                'translation')-1]
            percentage = pofile.percent_translated()
            print(basename, ("(%s" % percentage) + "%),", end=' ')
            if percentage >= PERCENTAGE:
                print("adding.")
                yield language
            else:
                print("NOT adding.")

    def get_semi_complete_languages(self):
        return [os.path.basename(a).split(".po")[0]
            for a in self.semi_complete_pofiles]

    def get_available_binary_packages(self):
        # metapackages and stuff
        BLACKLIST = ('ubuntu-packaging-guide',
                     'ubuntu-packaging-guide-common')
        with open(self.control_file) as control:
            stanzas = deb822.Packages.iter_paragraphs(control)
            result = [a for a in stanzas if "Package" in list(a.keys())
                and a.get("Package") not in BLACKLIST]
        return result

    def get_available_binary_package_names(self):
        return [a["Package"]
            for a in self.available_binary_packages]

    def get_base_package_names(self):
        base_packages = []
        for name in self.available_binary_package_names:
            is_translations_package = False
            for language in self.all_languages:
                if name.endswith("-%s" % self.fix_name(language)):
                    is_translations_package = True
            if not is_translations_package:
                base_packages += [name]
        return base_packages

    def get_package_name_permutations(self, languages):
        permutations = []
        for language in languages:
            permutations += ["%s-%s" % (pkg, self.fix_name(language))
                for pkg in self.base_package_names]
        return permutations

    def get_missing_binary_packages(self, languages):
        return [a for a in self.get_package_name_permutations(languages)
            if a not in self.available_binary_package_names]

    def add_to_control_file(self, language, template_name):
        new_package_name = "%s-%s" % (template_name,
            self.fix_name(language))
        template = list(filter(lambda a: a["Package"] == template_name,
                          self.available_binary_packages))[0]
        new_stanza = deb822.Packages()
        for key in template:
            new_stanza[key] = template[key]
        new_stanza["Package"] = new_package_name
        desc = new_stanza["Description"].split("\n")
        desc[0] += " - %s version" % self.language_names[language]
        desc[-1] = desc[-1].rstrip()
        desc += [" .", " This is the %s version." %
            self.language_names[language]]
        new_stanza["Description"] = "\n".join(desc)
        f = open(self.control_file, "a")
        f.write("\n")
        f.write(str(new_stanza))
        f.close()

    def add_installation_files(self, language, template_name):
        new_package_name = "%s-%s" % (template_name,
            self.fix_name(language))
        template_file = os.path.join(self.base_path,
                                     "debian/" + template_name + ".docs")
        new_file = os.path.join(self.base_path,
                                "debian/" + new_package_name + ".docs")
        doc_type = template_name.split("-")[-1]
        if template_name.endswith("html"):
            self.write_docs_file(template_file, new_file, doc_type, language)
            install_file = os.path.join(self.base_path,
                                        "debian/" + template_name + ".install")
            new_install_file = os.path.join(self.base_path,
                                            "debian/" + new_package_name +
                                            ".install")
            with open(install_file, "r") as install_file:
                lines = install_file.readlines()
            with open(new_install_file, "w") as new_install_file:
                for line in lines:
                    source, dest = line.split('\t')
                    source = source.replace("%s/" % doc_type,
                        "%s/%s/" % (doc_type, language))
                    dest = dest.replace("-%s/" % doc_type,
                        "-%s-%s/" % (doc_type, self.fix_name(language)))
                    new_install_file.write(source + '\t' + dest)
        else:
            self.write_docs_file(template_file, new_file, doc_type, language)

    def write_docs_file(self, template_file, new_file, doc_type, language):
        with open(template_file, "r") as template_file:
            lines = template_file.readlines()
        with open(new_file, "w") as new_file:
            for line in lines:
                new_file.write(line.replace("%s/" % doc_type,
                               "%s/%s/" % (doc_type, language)))

    def add_docbase_files(self, language, template_name):
        new_package_name = "%s-%s" % (template_name,
            self.fix_name(language))
        docbase_template = os.path.join(self.base_path,
                                        "debian/" + template_name +
                                        ".doc-base")
        new_docbase_file = os.path.join(self.base_path,
                                        "debian/" + new_package_name +
                                        ".doc-base")
        if template_name.endswith("html"):
            single_template = os.path.join(self.base_path,
                                           "debian/" + template_name +
                                           ".doc-base.single")
            new_single_file = os.path.join(self.base_path,
                                           "debian/" + new_package_name +
                                           ".doc-base.single")
            self.write_docbase_file(language, template_name, new_package_name,
                                    docbase_template, new_docbase_file)
            self.write_docbase_file(language, template_name, new_package_name,
                                    single_template, new_single_file)
        elif template_name.endswith("pdf"):
            self.write_docbase_file(language, template_name, new_package_name,
                                    docbase_template, new_docbase_file)
        else:
            pass

    def write_docbase_file(self, language, template_name, new_package_name,
                           template_file, new_file):
        doc_type = template_name.split("-")[-1]
        with open(template_file, "r") as template_file:
            lines = template_file.readlines()
        with open(new_file, "w") as new_file:
            for line in lines:
                if line.startswith("Document:"):
                    if line.endswith("-single\n"):
                        line = line[:-8] + ("-%s-single\n" % self.fix_name(language))
                    else:
                        line = line[:-1] + ("-%s\n" % self.fix_name(language))
                elif line.startswith("Index:") | line.startswith("Files:"):
                    line = line.replace("-%s" % doc_type,
                           "-%s-%s" % (doc_type, self.fix_name(language)))
                elif line.startswith("Title:"):
                    line = "Title: Ubuntu Packaging Guide - %s Version\n" \
                            % self.language_names[language]
                new_file.write(line)

    def add_to_makefile(self, language):
        with open(self.makefile, "r") as makefile:
            lines = makefile.readlines()
        with open(self.makefile, "w") as makefile:
            for line in lines:
                if line.startswith("LANGS =") and language not in line:
                    line = line.rstrip('\n') + " " + language + '\n'
                makefile.write(line)

    def add_package(self, package_name, language):
        language_code = self.fix_name(language)
        base_template = package_name.split('-'+language_code)[0]
        self.add_to_makefile(language)
        self.add_to_control_file(language, base_template)
        self.add_installation_files(language, base_template)
        self.add_docbase_files(language, base_template)


def main():
    package = Package()
    for language in package.semi_complete_languages:
        for name in package.get_missing_binary_packages((language,)):
            package.add_package(name, language)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.exit("Aborted.")
