#!/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
    "Argentina/ComodRivadavia",
    "Buenos_Aires",
    "Catamarca",
    "Cordoba",
    "Fort_Wayne",
    "Indianapolis",
    "Jujuy",
    "Knox_IN",
    "Louisville",
    "Mendoza",
    "Rosario",
    # Antarctica
    "South_Pole",
    # Asia
    "Ashkhabad",
    "Calcutta",
    "Chungking",
    "Dacca",
    "Katmandu",
    "Macao",
    "Saigon",
    "Thimbu",
    "Ulan_Bator",
    # Atlantic
    "Faeroe",
    # Australia
    "ACT",
    "LHI",
    "NSW",
    "North",
    "Queensland",
    "South",
    "Tasmania",
    "Victoria",
    "West",
    # Europe
    "Kiev",
    "Uzhgorod",
    "Zaporozhye",
    # Indian
    "East-Indiana",
    # Pacific
    "Enderbury",
}


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."""
    choices = get_timezones(zoneinfo_dir / area, zoneinfo_dir / area)
    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()
