#!/usr/bin/env python3
"""Finite teaching model: no Lucene, HTTP, disk, replication or election is executed."""
import copy
import json
from pathlib import Path


def run():
    fixture = json.loads(Path(__file__).with_name('fixture.json').read_text())
    realtime = {doc['item_id']: copy.deepcopy(doc) for doc in fixture['documents']}
    searchable = {}
    before = len(searchable)
    searchable = copy.deepcopy(realtime)  # model the publication of one search view
    pit = copy.deepcopy(searchable)
    version = 1
    expected = version
    if expected == version:
        version += 1
        first = 'updated'
    stale = 'updated' if expected == version else 'conflict'
    realtime['d'] = fixture['late_document']
    searchable = copy.deepcopy(realtime)
    order = lambda doc: (doc['created_at'], doc['item_id'])
    # Independent predicates expose cross-element matching versus same-element matching.
    flattened = [doc['item_id'] for doc in fixture['documents']
                 if any(a['key'] == 'color' for a in doc['attrs'])
                 and any(a['value'] == 'red' for a in doc['attrs'])]
    same = [doc['item_id'] for doc in fixture['documents']
            if any(a['key'] == 'color' and a['value'] == 'red' for a in doc['attrs'])]
    p = fixture['pagination']
    recovery = {case['case']: case['starting_seq_no'] >= 0 and case['same_history']
                and case['complete_history'] and case['retaining_seq_no'] <= case['starting_seq_no']
                for case in fixture['recovery']}
    result = {
        'kind': 'finite-model', 'baseline': 'Elasticsearch 8.15.1 / Lucene 9.11.1',
        'refresh': {'realtime_get': 'a' in realtime, 'search_before': before, 'search_after': len(pit)},
        'occ': {'first_update': first, 'stale_update': stale, 'current_version': version},
        'pagination': {'from_candidates': p['shards'] * (p['from'] + p['size']),
                       'pit_ids': [d['item_id'] for d in sorted(pit.values(), key=order)],
                       'live_ids': [d['item_id'] for d in sorted(searchable.values(), key=order)]},
        'nested': {'flattened_ids': flattened, 'same_element_ids': same}, 'recovery': recovery,
    }
    # Literal worked-example checks; model output is not evidence about a running server.
    assert result['pagination']['from_candidates'] == 1200240
    assert result['pagination']['pit_ids'] == ['a', 'b', 'c']
    assert flattened == ['a', 'b'] and same == ['a']
    assert version == 2 and stale == 'conflict'
    assert list(recovery.values()) == [True, False, False, False]
    return result


if __name__ == '__main__':
    print(json.dumps(run(), ensure_ascii=False, indent=2))
