#!/usr/bin/env python3
#
# Copyright (C) 2024 Wildfire Games.
# This file is part of 0 A.D.
#
# 0 A.D. is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# 0 A.D. is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.

import argparse
import multiprocessing
import os
import sys

from i18n_helper import L10N_FOLDER_NAME, PROJECT_ROOT_DIRECTORY
from i18n_helper.catalog import Catalog
from i18n_helper.globber import get_catalogs


DEBUG_PREFIX = "X_X "


def generate_long_strings(root_path, input_file_name, output_file_name, languages=None):
    """Generate the 'long strings' debug catalog.

    This catalog contains the longest singular and plural string,
    found amongst all translated languages or a filtered subset.
    It can be used to check if GUI elements are large enough.
    The catalog is long.*.po
    """
    print("Generating", output_file_name)
    input_file_path = os.path.join(root_path, input_file_name)
    output_file_path = os.path.join(root_path, output_file_name)

    template_catalog = Catalog.read_from(input_file_path)
    # Pretend we write English to get plurals.
    long_string_catalog = Catalog(locale="en")

    # Fill catalog with English strings.
    for message in template_catalog:
        long_string_catalog.add(
            id=message.id,
            string=message.id,
            context=message.context,
            auto_comments=message.auto_comments,
        )

    # Load existing translation catalogs.
    existing_translation_catalogs = get_catalogs(input_file_path, languages)

    # If any existing translation has more characters than the average expansion, use that instead.
    for translation_catalog in existing_translation_catalogs:
        for long_string_catalog_message in long_string_catalog:
            translation_message = translation_catalog.get(
                long_string_catalog_message.id, long_string_catalog_message.context
            )
            if not translation_message or not translation_message.string:
                continue

            if (
                not long_string_catalog_message.pluralizable
                or not translation_message.pluralizable
            ):
                if len(translation_message.string) > len(long_string_catalog_message.string):
                    long_string_catalog_message.string = translation_message.string
                continue

            longest_singular_string = translation_message.string[0]
            longest_plural_string = translation_message.string[
                1 if len(translation_message.string) > 1 else 0
            ]

            candidate_singular_string = long_string_catalog_message.string[0]
            # There might be between 0 and infinite plural forms.
            candidate_plural_string = ""
            for candidate_string in long_string_catalog_message.string[1:]:
                if len(candidate_string) > len(candidate_plural_string):
                    candidate_plural_string = candidate_string

            changed = False
            if len(candidate_singular_string) > len(longest_singular_string):
                longest_singular_string = candidate_singular_string
                changed = True
            if len(candidate_plural_string) > len(longest_plural_string):
                longest_plural_string = candidate_plural_string
                changed = True

            if changed:
                long_string_catalog_message.string = [
                    longest_singular_string,
                    longest_plural_string,
                ]
                translation_message = long_string_catalog_message
    long_string_catalog.write_to(output_file_path)


def generate_debug(root_path, input_file_name, output_file_name):
    """Generate a debug catalog to identify untranslated strings.

    This prefixes all strings with DEBUG_PREFIX, to easily identify
    untranslated strings while still making the game navigable.
    The catalog is debug.*.po
    """
    print("Generating", output_file_name)
    input_file_path = os.path.join(root_path, input_file_name)
    output_file_path = os.path.join(root_path, output_file_name)

    template_catalog = Catalog.read_from(input_file_path)
    # Pretend we write English to get plurals.
    out_catalog = Catalog(locale="en")

    for message in template_catalog:
        if message.pluralizable:
            out_catalog.add(
                id=message.id,
                string=(DEBUG_PREFIX + message.id[0],),
                context=message.context,
                auto_comments=message.auto_comments,
            )
        else:
            out_catalog.add(
                id=message.id,
                string=DEBUG_PREFIX + message.id,
                context=message.context,
                auto_comments=message.auto_comments,
            )

    out_catalog.write_to(output_file_path)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--debug",
        help="Generate debug localisation to identify non-translated strings.",
        action="store_true",
    )
    parser.add_argument(
        "--long",
        help="Generate 'long strings' localisation to identify GUI elements too small.",
        action="store_true",
    )
    parser.add_argument(
        "--languages", nargs="+", help="For long strings, restrict to these languages"
    )
    args = parser.parse_args()

    if not args.debug and not args.long:
        parser.print_help()
        sys.exit(0)

    found_pot_files = 0
    for root, _, filenames in os.walk(PROJECT_ROOT_DIRECTORY):
        for filename in filenames:
            if (
                len(filename) > 4
                and filename[-4:] == ".pot"
                and os.path.basename(root) == L10N_FOLDER_NAME
            ):
                found_pot_files += 1
                if args.debug:
                    multiprocessing.Process(
                        target=generate_debug, args=(root, filename, "debug." + filename[:-1])
                    ).start()
                if args.long:
                    multiprocessing.Process(
                        target=generate_long_strings,
                        args=(root, filename, "long." + filename[:-1], args.languages),
                    ).start()

    if found_pot_files == 0:
        print(
            "This script did not work because no '.pot' files were found. "
            "Please, run 'update_templates.py' to generate the '.pot' files, and run "
            "'pull_translations.py' to pull the latest translations from Transifex. "
            "Then you can run this script to generate '.po' files with obvious debug strings."
        )


if __name__ == "__main__":
    main()
