#!/usr/bin/env python

"""
Manipulate translation files.

Needed executables in path:

    * intltool-extract
    * msgfmt
    * msginit
    * msgmerge
    * xgettext

"""


import glob
import optparse
import os
import sys


TOOL_DIR   = os.path.dirname(os.path.abspath(__file__))
SOURCE_DIR = os.path.abspath(os.path.join(TOOL_DIR, '..'))
DATA_DIR   = os.path.join(SOURCE_DIR, 'data'  )
GLADE_DIR  = os.path.join(DATA_DIR  , 'glade' )
LIB_DIR    = os.path.join(SOURCE_DIR, 'lib'   )
LOCALE_DIR = os.path.join(SOURCE_DIR, 'locale')
PO_DIR     = os.path.join(SOURCE_DIR, 'po'    )
POT_FILE   = os.path.join(PO_DIR, 'gaupol.pot')


def compile_mo(lang):
    """Compile .mo file for language."""

    for lang in get_languages(lang):
        title_print('Compiling .mo file for language "%s"...' % lang)
        po_file = os.path.join(PO_DIR, '%s.po' % lang)
        mo_dir  = os.path.join(LOCALE_DIR, lang, 'LC_MESSAGES')
        mo_file = os.path.join(mo_dir, 'gaupol.mo')
        if not os.path.isdir(mo_dir):
            os.makedirs(mo_dir)
        os.system('msgfmt -cv %s -o %s' % (po_file, mo_file))

def create_po(lang):
    """Create .po file for a new language."""

    po_file = os.path.join(PO_DIR, '%s.po' % lang)
    if os.path.isfile(po_file):
        raise SystemExit('.po file for language "%s" already exists.' % lang)
    if not os.path.isfile(POT_FILE):
        create_pot()

    title_print('Creating .po file for language "%s"...' % lang)
    os.system('msginit -l %s -i %s -o %s' % (lang, POT_FILE, po_file))

def create_pot():
    """Create .pot file."""

    header_files = []
    python_files = []

    os.chdir(DATA_DIR)
    title_print('Extracting strings from desktop file...')
    os.system('intltool-extract --type=gettext/ini gaupol.desktop.in')
    header_files.append(os.path.abspath('gaupol.desktop.in' + '.h'))

    os.chdir(GLADE_DIR)
    title_print('Extracting strings from Glade XML files...')
    for filename in glob.glob('*.glade'):
        os.system('intltool-extract --type=gettext/glade %s' % filename)
        header_files.append(os.path.abspath(filename + '.h'))

    os.chdir(SOURCE_DIR)
    for (root, dirs, files) in os.walk('lib'):
        for name in files:
            if name.endswith('.py'):
                python_files.append(os.path.join(root, name))

    title_print('Creating .pot file from source files...')
    files = header_files + python_files
    files = list(x.replace(SOURCE_DIR, '.') for x in files)
    os.system('xgettext -k_ -kN_ -c -o %s %s' % (POT_FILE, ' '.join(files)))

    title_print('Removing temporary files...')
    for path in header_files:
        print path.replace(SOURCE_DIR, '.')
        os.remove(path)

def get_languages(lang):
    """
    Get list of languages.

    lang: locale or "all"
    """
    langs = []
    if lang == 'all':
        paths = glob.glob(os.path.join(PO_DIR, '*.po'))
        for path in paths:
            langs.append(os.path.basename(path)[:-3])
    else:
        langs.append(lang)
    langs.sort()
    return langs

def parse_args():
    """
    Parse arguments.

    Return: options, arguments
    """
    description = \
        'Create or update translation files. LANG should be a language code ' \
        'in either format "xx" or "xx_YY". Use "all" to  process all ' \
        'languages found in the "po" directory.'
    usage = 'translate OPTION'
    formatter = optparse.IndentedHelpFormatter(2, 42, None, True)
    parser = optparse.OptionParser(
        description=description,
        formatter=formatter,
        usage=usage,
    )

    parser.add_option(
        '-t',
        '--create-pot',
        action='store_true',
        dest='create_pot',
        default=False,
        help='create a new .pot file'
    )

    parser.add_option(
        '-p',
        '--create-po',
        action='store',
        type='string',
        metavar='LANG',
        dest='create_po',
        default='',
        help='create a new .po file'
    )
    parser.add_option(
        '-u',
        '--update-po',
        action='store',
        type='string',
        metavar='LANG',
        dest='update_po',
        default='',
        help='update an existing .po file'
    )
    parser.add_option(
        '-m',
        '--compile-mo',
        action='store',
        type='string',
        metavar='LANG',
        dest='compile_mo',
        default='',
        help='compile a .mo file'
    )

    return parser.parse_args(sys.argv)

def title_print(text):
    """Print a message that stands out from rest of the output."""

    print '** %s' % text

def update_po(lang):
    """Update existing .po files with new strings."""

    if not os.path.isfile(POT_FILE):
        create_pot()

    for lang in get_languages(lang):
        title_print('Updating .po file for language "%s"...' % lang)
        po_file = os.path.join(PO_DIR, '%s.po' % lang)
        os.system('msgmerge -U %s %s' % (po_file, POT_FILE))


opts, args = parse_args()
if opts.create_pot:
    create_pot()
elif opts.create_po:
    create_po(opts.create_po)
elif opts.update_po:
    update_po(opts.update_po)
elif opts.compile_mo:
    compile_mo(opts.compile_mo)
else:
    print 'Usage: translate [options]'
    print 'See "translate --help" for details.'
