#!/usr/bin/python3

# Author: Benjamin Drung <bdrung@ubuntu.com>

"""Generate tzdata debconf templates file."""

import argparse
import os
import pathlib

TEMPLATES_AREAS = [
    "Africa",
    "America",
    "Antarctica",
    "Arctic",
    "Asia",
    "Atlantic",
    "Australia",
    "Europe",
    "Indian",
    "Pacific",
    "US",
    "Etc",
]

# List of backward compatability symlinks that should not be selectable
EXCLUDE_SYMLINKS = {
    "Africa/Asmera",
    "America/Buenos_Aires",
    "America/Catamarca",
    "America/Cordoba",
    "America/Fort_Wayne",
    "America/Indianapolis",
    "America/Jujuy",
    "America/Knox_IN",
    "America/Louisville",
    "America/Mendoza",
    "Antarctica/South_Pole",
    "Asia/Ashkhabad",
    "Asia/Calcutta",
    "Asia/Chungking",
    "Asia/Dacca",
    "Asia/Katmandu",
    "Asia/Macao",
    "Asia/Rangoon",
    "Asia/Saigon",
    "Asia/Thimbu",
    "Asia/Ulan_Bator",
    "Atlantic/Faeroe",
    "Australia/ACT",
    "Australia/LHI",
    "Australia/NSW",
    "Australia/North",
    "Australia/Queensland",
    "Australia/South",
    "Australia/Tasmania",
    "Australia/Victoria",
    "Australia/West",
    "Europe/Kiev",
    "US/East-Indiana",
}


def get_timezones(base_dir: pathlib.Path, subdir: pathlib.Path) -> list[str]:
    """Return list of timezone files relative to the base_dir."""
    timezones = []
    for path in sorted(subdir.iterdir()):
        if path.is_dir():
            timezones += get_timezones(base_dir, path)
            continue
        timezone = str(path.relative_to(base_dir))
        if path.is_symlink() and timezone in EXCLUDE_SYMLINKS:
            continue
        timezones.append(timezone)
    return timezones


def generate_debconf_templates_area(zoneinfo_dir: pathlib.Path, area: str) -> str:
    """Generate tzdata debconf templates paragraph for given area."""
    timezones = get_timezones(zoneinfo_dir, zoneinfo_dir / area)
    choices = [timezone.split("/", maxsplit=1)[1] for timezone in timezones]
    if area == "Etc":
        choices_key = "Choices"
    else:
        choices_key = "__Choices"
    return f"""\
Template: tzdata/Zones/{area}
Type: select
# Translators: do not translate underscores. You can use spaces instead.
#flag:partial
{choices_key}: {", ".join(choices)}
_Description: Time zone:
 Please select the city or region corresponding to your time zone.
"""


def generate_debconf_templates(zoneinfo_dir: pathlib.Path) -> str:
    """Generate tzdata debconf templates file content."""
    debconf_templates = f"""\
# This file was generated by {pathlib.Path(__file__).relative_to(os.getcwd())}
#
Template: tzdata/Areas
Type: select
# Note to translators:
# - "Etc" will present users with a list
#    of "GMT+xx" or "GMT-xx" timezones
__Choices: {", ".join(TEMPLATES_AREAS)}
_Description: Geographic area:
 Please select the geographic area in which you live. Subsequent
 configuration questions will narrow this down by presenting a list of
 cities, representing the time zones in which they are located.
"""
    for area in TEMPLATES_AREAS:
        debconf_templates += "\n" + generate_debconf_templates_area(zoneinfo_dir, area)
    return debconf_templates


def existing_dir_path(string: str) -> pathlib.Path:
    """Convert string to existing dir path or raise ArgumentTypeError."""
    path = pathlib.Path(string)
    if not path.is_dir():
        raise argparse.ArgumentTypeError(f"Directory {string} does not exist")
    return path


def main() -> None:
    """Generate tzdata debconf templates file."""
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-d",
        "--directory",
        default=".",
        type=existing_dir_path,
        help="Directory containing the generated zoneinfo files",
    )
    args = parser.parse_args()
    print(generate_debconf_templates(args.directory), end="")


if __name__ == "__main__":
    main()
