"""Supervised receipt bookkeeping, not an authenticated approval provider."""
import datetime
import fcntl
import hashlib
import json
import os
import re
from pathlib import Path
import stat
import uuid

FOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}
MEMO_ID = 'infd-20261011-zlib-remediation-r1'
PROPOSAL = 'INFD-WP-0009-T05/zlib85091-r1'
PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',
          'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')


def require(value, reason):
    if not value:
        raise ValueError(reason)


def sha(path):
    digest = hashlib.sha256()
    with Path(path).open('rb') as stream:
        for block in iter(lambda: stream.read(1024**2), b''):
            digest.update(block)
    return digest.hexdigest()


def private(path, directory=False):
    info = Path(path).lstat()
    require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))
            and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)
            and (directory or info.st_nlink == 1), 'private owned custody required')


def authority(receipt, outcome, memo_sha, source_revision, phase, now=None):
    """Root must freshly verify native outcome at fixed ORIGIN outside this helper.

    Receipt files/flags are not signed grants. This function checks the exact
    supervised receipt relation; existing harness/founder authority remains the
    actual permission boundary. It never authenticates a caller as human.
    """
    now = now or datetime.datetime.now(datetime.timezone.utc)
    require(phase in PHASES, 'fixed phase required')
    require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID
            and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha
            and receipt.get('source_revision') == source_revision
            and receipt.get('activation') == 'APPROVED'
            and receipt.get('authority_mode') == 'ADMINISTER'
            and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'
            and receipt.get('verification_method') == 'root-fixed-origin-native-readback'
            and receipt.get('runtime_authenticated_grant') is False
            and receipt.get('outcome_query') == '/lifecycle/memos/' + MEMO_ID + '/outcomes?version=1',
            'exact externally verified supervised receipt required')
    verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))
    require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,
            'fresh root native readback required before every phase')
    deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')
    require(now < deadline, 'approved execution window expired')
    if phase == 'release':
        require((deadline-now).total_seconds() >= 1800, 'reserve thirty minutes for verification and recovery')
    require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False
            and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')
    review_id = outcome['review']['memo_id']
    require(review_id == receipt.get('review_memo_id'), 'native review identity changed')
    accepted = [x for x in outcome.get('dispositions', [])
                if x.get('submission_state') == 'confirmed'
                and x.get('disposition', {}).get('verb') == 'accept'
                and x['disposition'].get('memo_version') == 1]
    require(len(accepted) == 1, 'one confirmed founder acceptance required')
    accepted = accepted[0]['disposition']
    require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id
            and accepted.get('approval_id') == receipt.get('approval_id')
            and accepted.get('id') == receipt.get('disposition_id')
            and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')
    require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None
            and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None
            and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,
            'native disposition identifiers are malformed')
    accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))
    require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')
    return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}


class Journal:
    def __init__(self, parent, identity):
        self.parent = Path(parent)
        private(self.parent, directory=True)
        self.path = self.parent / 'execution-journal.json'
        self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)
        fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
        private(self.parent / 'execution.lock')
        if self.path.exists():
            private(self.path)
            self.data = json.loads(self.path.read_text())
            require(self.data['identity'] == identity, 'journal case/source identity changed')
        else:
            self.data = {'identity': identity, 'phases': {}}
            self.save()

    def save(self):
        temporary = self.parent / 'execution-journal.new'
        fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)
        try:
            with os.fdopen(fd, 'w') as stream:
                json.dump(self.data, stream, indent=2)
                stream.write('\n')
                stream.flush()
                os.fsync(stream.fileno())
            os.replace(temporary, self.path)
            directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)
            try:
                os.fsync(directory)
            finally:
                os.close(directory)
        except BaseException:
            # Retain evidence rather than overwriting an uncertain durable intent.
            raise

    def start(self, phase, approval):
        require(phase not in self.data['phases'], 'already attempted phase; no retry')
        predecessors = dict(zip(PHASES[1:8], PHASES[:7]))
        predecessors['rollback-verify'] = 'rollback'
        if phase in predecessors:
            require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',
                    'preceding phase is not verified complete')
        if phase == 'rollback':
            require('release' in self.data['phases'], 'rollback requires a recorded release attempt')
        self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,
                                      'attempt_id': str(uuid.uuid4()),
                                      'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}
        self.save()

    def note(self, phase, key, value):
        require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')
        self.data['phases'][phase][key] = value
        self.save()

    def finish(self, phase, result):
        entry = self.data['phases'][phase]
        require(entry['state'] == 'RUNNING', 'phase intent missing')
        entry['result'] = result
        entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'
        self.save()

    def close(self):
        os.close(self.lock)
