"""Install one InFinBot archive cron job on the current host, preserving other jobs.
Use --install only on your Mac. Sunday 23:59 uses the host's local timezone.
"""
import argparse
import json
import os
from pathlib import Path
import shlex
import shutil
import subprocess
import sys
from archive_tax_reports import create_password_file, load_password, private_directory, publish, read_regular, validate_report

MARKER = "# FORESIXA_TAX_ARCHIVE_V1"
PROJECT = Path(__file__).resolve().parent.parent


def cron_quote(value):
    value = str(value)
    if any(c in value for c in "\n\r\x00"):
        raise ValueError("Invalid cron path")
    return shlex.quote(value).replace("%", "\\%")


def schedule_line(python, project, password_file, log):
    script = project / "generated/archive_tax_reports.py"
    command = " ".join(cron_quote(x) for x in
                       (python, script, "--password-file", password_file, "--non-interactive"))
    return "59 23 * * 0 " + command + " >> " + cron_quote(log) + " 2>&1"


def merge_crontab(existing, job):
    lines = existing.splitlines()
    kept = []
    index = 0
    while index < len(lines):
        line = lines[index]
        if line.strip() == MARKER:
            if index + 1 >= len(lines) or "archive_tax_reports.py" not in lines[index+1]:
                raise ValueError("Existing managed cron entry is inconsistent; no changes made")
            index += 2
            continue
        if line.strip() and not line.lstrip().startswith("#") and "archive_tax_reports.py" in line:
            raise ValueError("An unmarked archive job already exists; inspect it before replacing it")
        kept.append(line)
        index += 1
    return "\n".join(kept + [MARKER, job]) + "\n"


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--install", action="store_true", help="Install on this host; omission prints a proposed cron entry only")
    parser.add_argument("--password-file", default=str(PROJECT / "private/archive-password.txt"))
    args = parser.parse_args()
    password_file = Path(args.password_file).absolute()
    log = PROJECT / "private/archive_cron.log"
    job = schedule_line(sys.executable, PROJECT, password_file, log)
    if not args.install:
        print(MARKER + "\n" + job)
        print("# Proposed only. Host local timezone; no schedule installed.")
        return 0
    try:
        if sys.platform != "darwin":
            raise ValueError("Installation is intended for the user's Mac, not this workspace")
        local_zone = str(Path("/etc/localtime").resolve())
        if not local_zone.endswith(("/America/New_York", "/US/Eastern")):
            raise ValueError("Confirm/set the Mac timezone to America/New_York before installation")
        crontab = shutil.which("crontab")
        if not crontab:
            raise ValueError("Host crontab is unavailable")
        import cryptography  # Required in this exact interpreter for cron too.
        validate_report(read_regular(PROJECT / "generated/automated_irs_form_8949.json", 32*1024*1024))
        if password_file.exists() or password_file.is_symlink():
            load_password(password_file, non_interactive=True)
        else:
            create_password_file(password_file)
        private_directory(log.parent)
        if not log.exists() and not log.is_symlink():
            publish(log, b"")
        read_regular(log, 32*1024*1024, private=True)
        before = subprocess.run([crontab, "-l"], capture_output=True, text=True)
        if before.returncode == 0:
            existing = before.stdout
        elif before.returncode == 1 and "no crontab" in before.stderr.lower():
            existing = ""
        else:
            raise ValueError("Existing crontab could not be read; no schedule changed")
        updated = merge_crontab(existing, job)
        result = subprocess.run([crontab, "-"], input=updated, capture_output=True, text=True)
        if result.returncode:
            raise ValueError("Crontab installation was rejected")
        verified = subprocess.run([crontab, "-l"], capture_output=True, text=True)
        if verified.returncode or verified.stdout.strip() != updated.strip():
            raise ValueError("Crontab readback could not confirm the installation; inspect on the host before retrying")
        print(json.dumps({"status":"CRON_INSTALLED_AND_READ_BACK", "when":"Sunday 23:59 host local time",
                          "host_timezone_must_be":"America/New_York for the requested timing",
                          "first_run_verified":False, "password_displayed":False,
                          "source_deletion_enabled":False, "other_cron_jobs_preserved":True}, indent=2))
        return 0
    except ImportError:
        reason = "Install cryptography in the Python environment used for this installer"
    except FileNotFoundError:
        reason = "Required current export is missing; no schedule installed or synthetic export created"
    except UnicodeError:
        reason = "Private input must be valid UTF-8"
    except ValueError as exc:
        reason = str(exc)
    except OSError:
        reason = "Setup blocked or unconfirmed: inspect host export, private password/log paths and existing cron jobs"
    print(json.dumps({"status":"SCHEDULE_UNCONFIRMED", "reason":reason, "host_run_verified":False}, indent=2))
    return 1


if __name__ == "__main__":
    raise SystemExit(main())
