# 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.
from __future__ import annotations

import os
import argparse
import subprocess
import tempfile
import shutil
import typing as T

parser = argparse.ArgumentParser()
parser.add_argument('command')
parser.add_argument('--build-dir', default='')
parser.add_argument('-i', '--input', default='')
parser.add_argument('-o', '--output', default='')
parser.add_argument('--itstool', default='itstool')
parser.add_argument('--its', action='append', default=[])
parser.add_argument('mo_files', nargs='+')


def run_join(build_dir: str, itstool: str, its_files: T.List[str], mo_files: T.List[str],
             in_fname: str, out_fname: str) -> int:
    if not mo_files:
        print('No mo files specified to use for translation.')
        return 1

    with tempfile.TemporaryDirectory(prefix=os.path.basename(in_fname), dir=build_dir) as tmp_dir:
        # copy mo files to have the right names so itstool can infer their locale
        locale_mo_files = []
        for mo_file in mo_files:
            if not os.path.exists(mo_file):
                print(f'Could not find mo file {mo_file}')
                return 1
            if not mo_file.endswith('.mo'):
                print(f'File is not a mo file: {mo_file}')
                return 1
            # determine locale of this mo file
            parts = mo_file.partition('LC_MESSAGES')
            if parts[0].endswith((os.sep, '/')):
                locale = os.path.basename(parts[0][:-1])
            else:
                locale = os.path.basename(parts[0])
            tmp_mo_fname = os.path.join(tmp_dir, locale + '.mo')
            shutil.copy(mo_file, tmp_mo_fname)
            locale_mo_files.append(tmp_mo_fname)

        cmd = [itstool]
        if its_files:
            for fname in its_files:
                cmd.extend(['-i', fname])
        cmd.extend(['-j', in_fname,
                    '-o', out_fname])
        cmd.extend(locale_mo_files)

        return subprocess.call(cmd)


def run(args: T.List[str]) -> int:
    options = parser.parse_args(args)
    command = options.command
    build_dir = os.environ.get('MESON_BUILD_ROOT', os.getcwd())
    if options.build_dir:
        build_dir = options.build_dir

    if command == 'join':
        return run_join(build_dir,
                        options.itstool,
                        options.its,
                        options.mo_files,
                        options.input,
                        options.output)
    else:
        print('Unknown subcommand.')
        return 1
