# Copyright 2016 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import shutil
import argparse
import subprocess
from . import destdir_join
import typing as T

parser = argparse.ArgumentParser()
parser.add_argument('command')
parser.add_argument('--pkgname', default='')
parser.add_argument('--datadirs', default='')
parser.add_argument('--langs', default='')
parser.add_argument('--localedir', default='')
parser.add_argument('--subdir', default='')
parser.add_argument('--extra-args', default='')

def read_linguas(src_sub: str) -> T.List[str]:
    # Syntax of this file is documented here:
    # https://www.gnu.org/software/gettext/manual/html_node/po_002fLINGUAS.html
    linguas = os.path.join(src_sub, 'LINGUAS')
    try:
        langs = []
        with open(linguas) as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#'):
                    langs += line.split()
        return langs
    except (FileNotFoundError, PermissionError):
        print(f'Could not find file LINGUAS in {src_sub}')
        return []

def run_potgen(src_sub: str, pkgname: str, datadirs: str, args: T.List[str]) -> int:
    listfile = os.path.join(src_sub, 'POTFILES.in')
    if not os.path.exists(listfile):
        listfile = os.path.join(src_sub, 'POTFILES')
        if not os.path.exists(listfile):
            print('Could not find file POTFILES in %s' % src_sub)
            return 1

    child_env = os.environ.copy()
    if datadirs:
        child_env['GETTEXTDATADIRS'] = datadirs

    ofile = os.path.join(src_sub, pkgname + '.pot')
    return subprocess.call(['xgettext', '--package-name=' + pkgname, '-p', src_sub, '-f', listfile,
                            '-D', os.environ['MESON_SOURCE_ROOT'], '-k_', '-o', ofile] + args,
                           env=child_env)

def gen_gmo(src_sub: str, bld_sub: str, langs: T.List[str]) -> int:
    for l in langs:
        subprocess.check_call(['msgfmt', os.path.join(src_sub, l + '.po'),
                               '-o', os.path.join(bld_sub, l + '.gmo')])
    return 0

def update_po(src_sub: str, pkgname: str, langs: T.List[str]) -> int:
    potfile = os.path.join(src_sub, pkgname + '.pot')
    for l in langs:
        pofile = os.path.join(src_sub, l + '.po')
        if os.path.exists(pofile):
            subprocess.check_call(['msgmerge', '-q', '-o', pofile, pofile, potfile])
        else:
            subprocess.check_call(['msginit', '--input', potfile, '--output-file', pofile, '--locale', l, '--no-translator'])
    return 0

def do_install(src_sub: str, bld_sub: str, dest: str, pkgname: str, langs: T.List[str]) -> int:
    for l in langs:
        srcfile = os.path.join(bld_sub, l + '.gmo')
        outfile = os.path.join(dest, l, 'LC_MESSAGES',
                               pkgname + '.mo')
        tempfile = outfile + '.tmp'
        os.makedirs(os.path.dirname(outfile), exist_ok=True)
        shutil.copy2(srcfile, tempfile)
        os.replace(tempfile, outfile)
        if not os.getenv('MESON_INSTALL_QUIET', False):
            print(f'Installing {srcfile} to {outfile}')
    return 0

def run(args: T.List[str]) -> int:
    options = parser.parse_args(args)
    subcmd = options.command
    langs = options.langs.split('@@') if options.langs else None
    extra_args = options.extra_args.split('@@') if options.extra_args else []
    subdir = os.environ.get('MESON_SUBDIR', '')
    if options.subdir:
        subdir = options.subdir
    src_sub = os.path.join(os.environ['MESON_SOURCE_ROOT'], subdir)
    bld_sub = os.path.join(os.environ['MESON_BUILD_ROOT'], subdir)

    if not langs:
        langs = read_linguas(src_sub)

    if subcmd == 'pot':
        return run_potgen(src_sub, options.pkgname, options.datadirs, extra_args)
    elif subcmd == 'gen_gmo':
        return gen_gmo(src_sub, bld_sub, langs)
    elif subcmd == 'update_po':
        if run_potgen(src_sub, options.pkgname, options.datadirs, extra_args) != 0:
            return 1
        return update_po(src_sub, options.pkgname, langs)
    elif subcmd == 'install':
        destdir = os.environ.get('DESTDIR', '')
        dest = destdir_join(destdir, os.path.join(os.environ['MESON_INSTALL_PREFIX'],
                                                  options.localedir))
        if gen_gmo(src_sub, bld_sub, langs) != 0:
            return 1
        do_install(src_sub, bld_sub, dest, options.pkgname, langs)
    else:
        print('Unknown subcommand.')
        return 1
    return 0
