#!/usr/bin/env python3
"""
Handle localization

Author: Arjen Balfoort
Date: 2026-02-24
"""

import os
import sys
import re
import json
import subprocess
import shutil
from pathlib import Path
from utils import is_link_pointing_to

# If set to True, no changes will be made
DEBUG = False


def run_command(command: list):
    """
    Run a command and print its output.
    The print is flushed to ensure that the output is immediately
    visible and can be used by the PackageManagerThread class.
    """
    print(f"Running command: {' '.join(command)}", flush=True)

    # stdbuf -oL forces line buffering for the output of apt-get.
    command = ["stdbuf", "-oL"] + command

    try:
        # Get the current environment and update it
        env = os.environ.copy()
        env['DEBIAN_FRONTEND'] = 'noninteractive'

        with subprocess.Popen(
            command,
            env=env,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
            bufsize=1
        ) as process:
            for line in process.stdout:
                print(line.strip(), flush=True)
            process.wait()
            if process.returncode != 0:
                print(f"Error: Command failed with return code {process.returncode}", flush=True)
                sys.exit(1)
    except Exception as e:
        print(f"Error: {e}", flush=True)
        sys.exit(1)

def main():
    if len(sys.argv) != 3:
        print("Usage: python3 localize_sudo.py <json_file> <timezone>")
        sys.exit(1)

    json_file = sys.argv[1]
    timezone = sys.argv[2]
    print(f"JSON file: {json_file}, Timezone: {timezone}")

    try:
        with open(json_file, 'r', encoding='utf-8') as f:
            installed_locales = json.load(f)
    except Exception as e:
        print(f"Failed to read JSON file: {e}")
        sys.exit(2)

    locale_gen = Path('/etc/locale.gen')
    if not locale_gen.exists():
        print("Error: /etc/locale.gen does not exist.")
        sys.exit(3)

    for locale, settings in installed_locales.items():
        installed = settings['installed']
        default = settings['default']
        packages = settings['packages']
        print(f"Locale: {locale}, Installed: {installed}, Default: {default}")

        try:
            content = locale_gen.read_text(encoding='utf-8').splitlines()
            locale_found = False
            locale_changed = False
            for i, line in enumerate(content):
                if f'{locale}.UTF-8' in line:
                    locale_found = True
                    if installed and line.startswith('#'):
                        print(f"Uncommenting {line} in {str(locale_gen)}")
                        content[i] = re.sub(r'#\s*', '', line)
                        locale_changed = True
                    elif not installed and not line.startswith('#'):
                        print(f"Commenting {line} in {str(locale_gen)}")
                        content[i] = f"# {line}"
                        locale_changed = True
                    break
            if not locale_found and installed:
                print(f"Adding {locale} to {str(locale_gen)}")
                content.append(f"{locale}.UTF-8 UTF-8")
                locale_changed = True

            if locale_changed:
                if not DEBUG:
                    locale_gen.write_text('\n'.join(content), encoding='utf-8')

                # Run locale-gen
                run_command(["locale-gen"])

            if default:
                default_locale = Path("/etc/default/locale")
                locale_string = f'LANG={locale}.UTF-8\nLC_ALL={locale}.UTF-8\nLANGUAGE={locale}.UTF-8\n'
                print(f"Writing {locale_string} to {str(default_locale)}")
                if not DEBUG:
                    default_locale.write_text(locale_string, encoding='utf-8')

            if timezone:
                timezone_path = Path("/etc/timezone")
                print(f"Writing {timezone} to {str(timezone_path)}")
                if not DEBUG:
                    timezone_path.write_text(f"{timezone}\n", encoding='utf-8')

                localtime_path = Path("/etc/localtime")
                zoneinfo_path = Path(f"/usr/share/zoneinfo/{timezone}")
                if localtime_path.exists() and \
                   not is_link_pointing_to(localtime_path, zoneinfo_path):
                    print(f"Symlinking {str(localtime_path)} to {str(zoneinfo_path)}")
                    if not DEBUG:
                        localtime_path.unlink()
                        localtime_path.symlink_to(zoneinfo_path)

                lang_code = locale.split('_')[0]
                grub_mo_src = Path(f"/usr/share/locale/{lang_code}/LC_MESSAGES/grub.mo")
                grub_mo_dst = Path(f"/boot/grub/locale/{lang_code}.mo")
                if grub_mo_src.exists() and not grub_mo_dst.exists():
                    print(f"Copying {str(grub_mo_src)} to {str(grub_mo_dst)}")
                    if not DEBUG:
                        grub_mo_dst.parent.mkdir(parents=True, exist_ok=True)
                        shutil.copyfile(str(grub_mo_src), str(grub_mo_dst))

        except Exception as e:
            print(f"Error processing locale {locale}: {e}")
            sys.exit(1)

        # Install packages
        for package in packages:
            print(f"Installing {package}")
            if not DEBUG:
                run_command(["apt-get", "install", "-y", package])

    print("localize_sudo.py completed successfully.")
    sys.exit(0)

if __name__ == "__main__":
    # Start logging
    print("localize_sudo.py started.")
    main()
