# -*- coding: utf-8 -*-
"""
    sphinxjp-gettext-helper
    ~~~~~~~~~~~~~~~~~~~~~~~~

    This package is a namespace package that contains all extensions
    distributed in the ``sphinxjp-gettext-helper`` distribution.

    :copyright: Copyright 2011 by Takeshi Komiya <i.tkomiya@gmail.com>
    :license: BSD, see LICENSE for details.
"""

import os
import sys
import re
from optparse import OptionParser


def parse_option():
    p = OptionParser()
    p.add_option('-b', '--build', action='store_true',
                 help='build message catalogs')
    p.add_option('-c', '--config', default="conf.py",
                 help='read configurations from FILE', metavar='FILE')
    p.add_option('-l', '--language',
                 help='target language')
    p.add_option('-p', '--potdir',
                 help='pot files directory which is generated by sphinx')
    p.add_option('-s', '--statistics', action='store_true',
                 help='show translation statistics')
    p.add_option('-u', '--update', action='store_true',
                 help='update message catalogs')
    options, args = p.parse_args()

    if len(args) > 0:
        p.print_help()
        sys.exit(0)

    if not options.build and not options.update:
        msg = "Specify --build or --update option"
        raise RuntimeError(msg)

    if not options.potdir:
        msg = "Specify --potdir option"
        raise RuntimeError(msg)

    if not os.path.isfile(options.config):
        msg = "config file is not found: %s" % options.config
        raise RuntimeError(msg)

    config = read_config(options.config)
    if 'language' not in config or 'locale_dirs' not in config:
        msg = "language and locale_dirs was not defined: %s" % options.config
        raise RuntimeError(msg)

    if options.language is None:
        options.language = config['language']

    if options.language is None:
        msg = "No languages are selected"
        raise RuntimeError(msg)

    options.locale_dir = os.path.join(config['locale_dirs'][0],
                                      options.language, 'LC_MESSAGES')

    if options.language == 'C':
        # do nothing for locale=C
        sys.exit(0)

    return options, args


def read_config(path):
    namespace = {}
    olddir = os.getcwd()
    try:
        os.chdir(os.path.dirname(path) or ".")
        execfile(path, namespace)
    finally:
        os.chdir(olddir)

    return namespace


def do_update(options):
    for dirpath, dirnames, filenames in os.walk(options.potdir):
        for filename in filenames:
            file = os.path.join(dirpath, filename)
            base, ext = os.path.splitext(file)
            if ext != ".pot":
                continue
            basename = os.path.relpath(base, options.potdir)
            pofile = os.path.join(options.locale_dir, basename + ".po")

            outdir = os.path.dirname(pofile)
            if not os.path.exists(outdir):
                os.makedirs(outdir)

            if os.path.isfile(pofile):
                cmd = "msgmerge -q -U %s %s" % (pofile, file)
            else:
                cmd = "msginit --no-translator --locale=%s --input=%s --output=%s" % \
                      (options.language, file, pofile)

            os.system(cmd)


def do_build(options):
    for dirpath, dirnames, filenames in os.walk(options.locale_dir):
        for filename in filenames:
            file = os.path.join(dirpath, filename)
            base, ext = os.path.splitext(file)
            if ext != ".po":
                continue

            mofile = base + ".mo"

            if options.statistics:
                cmd = "msgfmt --statistics %s -o %s" % (file, mofile)
            else:
                cmd = "msgfmt %s -o %s" % (file, mofile)

            os.system(cmd)


def main():
    try:
        options, args = parse_option()
    except RuntimeError, e:
        sys.stderr.write("ERROR: %s\n" % e)
        return

    if not os.path.exists(options.locale_dir):
        os.makedirs(options.locale_dir)

    if options.update:
        do_update(options)

    if options.build:
        do_build(options)
