"""Install managed InFinBot host jobs, preserving unrelated crontab entries."""
import argparse,json,subprocess,sys,shlex
from pathlib import Path
from infinbot_common import private_read,strict_json,private_dir,Rejected

BEGIN='# INFINBOT_HOST_JOBS_V1'
END='# END_INFINBOT_HOST_JOBS_V1'


def quote(value):
    value=str(value)
    if any(x in value for x in ('\r','\n','\x00')):raise Rejected('Invalid scheduler path')
    return shlex.quote(value).replace('%','\\%')


def block(config_path):
    root=Path(__file__).resolve().parent;config=strict_json(private_read(config_path))
    log=Path(config['receipt_dir']).parent/'infinbot-schedule.log'
    if log.is_symlink():raise Rejected('Unsafe schedule log')
    if not log.exists():
        import os
        fd=os.open(log,os.O_CREAT|os.O_EXCL|os.O_WRONLY,0o600);os.close(fd)
    private_read(log,32*1024*1024)
    prefix=quote(sys.executable)+' '
    tail=' --config '+quote(Path(config_path).absolute())+' >> '+quote(log)+' 2>&1'
    return '\n'.join([BEGIN,
        '55 23 * * 5 '+prefix+quote(root/'infinbot_backup.py')+tail,
        '50 23 * * 0 '+prefix+quote(root/'infinbot_acceptance.py')+tail,
        '59 23 * * 0 '+prefix+quote(root/'infinbot_archive_job.py')+tail,END])+'\n'


def merge(existing,new):
    lines=existing.splitlines();result=[];inside=False;seen=False
    for line in lines:
        if line==BEGIN:
            if inside or seen:raise Rejected('Duplicate/malformed managed blocks')
            inside=True;seen=True;continue
        if line==END:
            if not inside:raise Rejected('Unmatched managed block')
            inside=False;continue
        if inside:continue
        if line and not line.lstrip().startswith('#') and any(x in line for x in ('archive_tax_reports.py','infinbot_acceptance.py','infinbot_backup.py','infinbot_archive_job.py')):
            raise Rejected('Existing unmarked/legacy job found; remove duplicate only after review')
        result.append(line)
    if inside:raise Rejected('Unclosed managed block')
    return '\n'.join(result)+'\n'+new


def main():
    p=argparse.ArgumentParser();p.add_argument('--config',required=True);p.add_argument('--install',action='store_true');args=p.parse_args()
    try:
        if args.install:
            if sys.platform!='darwin' or not str(Path('/etc/localtime').resolve()).endswith(('/America/New_York','/US/Eastern')):
                raise Rejected('Install only on the intended Mac with New York timezone')
        proposed=block(args.config)
        if not args.install:print(proposed);return 0
        before=subprocess.run(['crontab','-l'],capture_output=True,text=True,timeout=5)
        if before.returncode and not (before.returncode==1 and 'no crontab' in before.stderr.lower()):raise Rejected('Cannot read existing scheduler')
        updated=merge(before.stdout if not before.returncode else '',proposed)
        done=subprocess.run(['crontab','-'],input=updated,capture_output=True,text=True,timeout=5)
        after=subprocess.run(['crontab','-l'],capture_output=True,text=True,timeout=5)
        if done.returncode or after.returncode or after.stdout.strip()!=updated.strip():raise Rejected('Schedule install unconfirmed; inspect before retry')
        print(json.dumps({'status':'HOST_SCHEDULE_INSTALLED_AND_READ_BACK','timezone':'America/New_York','first_scheduled_run_verified':False,'other_jobs_preserved':True}));return 0
    except Exception:print(json.dumps({'status':'SCHEDULE_BLOCKED_OR_UNCONFIRMED','reason':'Host timezone, existing jobs and private configuration require review'}));return 1


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