#!/usr/bin/python

#
# 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
#

import copy
import glob
import sys
import os
import re

try:
    import polib
except:
    print >> sys.stderr, "You need to have  python-polib  installed."
    sys.exit(1)

try:
    from debian import deb822
except:
    print >> sys.stderr, "You need to have  python-debian  installed."
    sys.exit(1)

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.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 get_all_pofiles(self):
        return map(lambda a: os.path.abspath(a),
                   glob.glob("%s/*.po" % self.po_path))
    
    def get_all_languages(self):
        return map(lambda a: os.path.basename(a).split(".po")[0],
                   self.all_pofiles)

    def get_semi_complete_pofiles(self):
        languages = self.all_pofiles
        complete = []
        for language in languages:
            pofile = polib.pofile(language)
            percentage = pofile.percent_translated()
            print os.path.basename(language), ("(%s" % percentage)+"%),",
            if percentage >= PERCENTAGE:
                print "adding."
                complete += [ language ]
            else:
                print "NOT adding."
        return complete

    def get_semi_complete_languages(self):
        return map(lambda a: os.path.basename(a).split(".po")[0],
                   self.semi_complete_pofiles)

    def get_available_binary_packages(self):
        BLACKLIST = [u'ubuntu-packaging-guide']     # metapackages and stuff
        self.stanzas = deb822.Packages.iter_paragraphs(open(self.control_file))
        return filter(lambda a: "Package" in a.keys() and \
                                a.get("Package") not in BLACKLIST, self.stanzas)

    def get_available_binary_package_names(self):
        return map(lambda a: a["Package"], 
                   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" % 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 +=  map(lambda pkg: "%s-%s" % (pkg, language),
                                 self.base_package_names)
        return permutations

    def get_missing_binary_packages(self, languages):
        return filter(lambda a: a not in self.available_binary_package_names,
                      self.get_package_name_permutations(languages))

    def add_to_control_file(self, language, template_name):
        new_package_name = "%s-%s" % (template_name, language)
        template = filter(lambda a: a["Package"] == template_name,
                          self.available_binary_packages)[0]
        new_stanza = copy.copy(template)
        new_stanza["Package"] = new_package_name
        desc = new_stanza["Description"].split("\n")
        desc[0] += " - '%s' version" % language
        desc[-1] = desc[-1].rstrip()
        desc += [ " .", " This is the '%s' version." % language ]
        new_stanza["Description"] = "\n".join(desc)
        f = open(self.control_file, "a")
        f.write(u"\n")
        f.write(unicode(new_stanza))
        f.close()

    def add_installation_files(self, language, template_name):
        new_package_name = "%s-%s" % (template_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 = re.sub("%s/" % doc_type,
                                          "%s/%s/" % (doc_type, language),
                                          line.split('\t')[0])
                    dest = re.sub("-%s/" % doc_type,
                                          "-%s-%s/" % (doc_type, language),
                                          line.split('\t')[-1])
                    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(re.sub("%s/" % doc_type,
                                      "%s/%s/" % (doc_type, language),
                                      line))

    def add_docbase_files(self, language, template_name):
        new_package_name = "%s-%s" % (template_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:"):
                     line = "Document: " + new_package_name + "\n"
                 elif line.startswith("Index:") | line.startswith("Files:"):
                     line = re.sub("-%s" % doc_type, "-%s-%s" % (doc_type, language), line)
                 elif line.startswith("Title:"):
                     line = "Title: Ubuntu Packaging Guide - %s Version\n" % language
                 else:
                     line = line
                 new_file.write(line)

    def add_package(self, package_name):
        base_template = "-".join(package_name.split("-")[0:-1])
        language = package_name.split("-")[-1]
        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 name in package.get_missing_binary_packages(package.semi_complete_languages):
        package.add_package(name)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print >> sys.stderr, "Aborted."
        sys.exit(1)
