#!/usr/bin/env python3
"""Change the /admin password in this application's .env file."""

import argparse
import getpass
import os
from pathlib import Path
import stat
import sys

from dotenv import dotenv_values, set_key


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--env-file", type=Path,
        default=Path(__file__).resolve().parents[1] / ".env",
        help="Application .env path (defaults to the project .env)",
    )
    args = parser.parse_args()
    env_file = args.env_file.resolve()
    if not env_file.is_file():
        parser.error(f"Existing .env file not found: {env_file}")
    if not sys.stdin.isatty():
        parser.error("Run interactively in a terminal to enter the password securely.")

    password = getpass.getpass("New admin password (minimum 12 characters): ")
    if len(password) < 12:
        parser.error("Use at least 12 characters.")
    if password != password.strip() or any(c in password for c in "\r\n\x00"):
        parser.error("Password cannot contain line breaks, NUL, or leading/trailing whitespace.")
    if password != getpass.getpass("Confirm new admin password: "):
        parser.error("Passwords do not match. Nothing changed.")

    mode = stat.S_IMODE(env_file.stat().st_mode)
    try:
        # Quoting preserves special characters, including dollar signs and hashes.
        set_key(str(env_file), "ADMIN_PASSWORD", password, quote_mode="always")
    finally:
        os.chmod(env_file, mode)
    saved = dotenv_values(env_file, interpolate=False).get("ADMIN_PASSWORD")
    if saved != password:
        raise RuntimeError("Password verification failed; inspect the .env configuration.")
    print(f"Admin password updated in {env_file}")
    print("Restart the application service to apply the new password.")
    print("If ADMIN_PASSWORD is also set by your server/container, update that setting too;")
    print("server environment variables take priority over .env.")


if __name__ == "__main__":
    try:
        main()
    except (KeyboardInterrupt, EOFError):
        sys.exit("\nCancelled.")
