from pathlib import Path
from tempfile import TemporaryDirectory

from django.conf import settings
from django.core.management import call_command
from django.core.management.base import BaseCommand, CommandError

from ._dbutils import base_connection_args, decrypt_backup_to, pg_config, pg_env, require_binary, run_checked


class Command(BaseCommand):
    help = "Guarded PostgreSQL restore. Takes a pre-restore backup and requires exact DB/project confirmations."

    def add_arguments(self, parser):
        parser.add_argument("file")
        parser.add_argument("--confirm-db", required=True)
        parser.add_argument("--confirm-project", required=True)
        parser.add_argument("--skip-pre-backup", action="store_true")

    def handle(self, *args, **options):
        cfg = pg_config()
        if options["confirm_db"] != str(cfg["NAME"]):
            raise CommandError("Database confirmation does not match DB_NAME.")
        if options["confirm_project"] != settings.PROJECT_REFERENCE:
            raise CommandError("Project confirmation does not match PROJECT_REFERENCE.")

        path = Path(options["file"]).expanduser().resolve()
        if not path.is_file():
            raise CommandError(f"Backup not found: {path}")

        call_command("verify_backup", str(path))
        if not options["skip_pre_backup"]:
            call_command("backup_database", prefix="pre-restore", no_retention=True)

        pg_restore = require_binary("pg_restore")
        with TemporaryDirectory(prefix="hrpay-restore-") as tmp:
            plaintext = Path(tmp) / "restore.dump"
            decrypt_backup_to(path, plaintext)
            cmd = [
                pg_restore,
                "--clean",
                "--if-exists",
                "--no-owner",
                "--no-privileges",
                *base_connection_args(cfg),
                "--dbname", str(cfg["NAME"]),
                str(plaintext),
            ]
            run_checked(cmd, env=pg_env(cfg))
        self.stdout.write(self.style.SUCCESS("Restore completed. Run migrations/checks and application smoke tests before reopening user access."))
