#!/usr/bin/env python3
"""Fictional mirror-source candidate inventory; no monday API parser or writer.

Normalized links and configuration are supplied observations. Configuration
fingerprints, qualification flags and approved targets are local inputs, not
native API fields. A proposed target is not a mutation or a permission proof.
"""
from dataclasses import dataclass, replace
from itertools import permutations
import json
import sys


@dataclass(frozen=True, order=True)
class Cell:
    board: str
    item: str
    column: str


@dataclass(frozen=True)
class Link:
    board: str
    item: str


@dataclass(frozen=True)
class Configuration:
    board: str
    columns: tuple[str, ...]


@dataclass(frozen=True)
class Snapshot:
    mirror: Cell
    links: tuple[Link, ...]
    configuration: tuple[Configuration, ...]
    expected_fingerprint: str
    observed_fingerprint: str
    inventory_qualified: bool = True
    source_types_qualified: bool = True
    source_access_qualified: bool = True
    business_write_authorized: bool = False


def identifier(value):
    return type(value) is str and bool(value.strip()) and value == value.strip()


def validate(snapshot, approved_target):
    if not isinstance(snapshot, Snapshot) or not isinstance(snapshot.mirror, Cell):
        raise ValueError('outside_local_snapshot')
    for cell in [snapshot.mirror]+([approved_target] if approved_target is not None else []):
        if not isinstance(cell, Cell) or not all(identifier(x) for x in (cell.board, cell.item, cell.column)):
            raise ValueError('invalid_local_cell_identity')
    if not isinstance(snapshot.links, tuple) or not isinstance(snapshot.configuration, tuple):
        raise ValueError('immutable_local_inventory_required')
    if not all(isinstance(x, Link) and identifier(x.board) and identifier(x.item) for x in snapshot.links):
        raise ValueError('invalid_local_link')
    boards = set()
    for conf in snapshot.configuration:
        if (not isinstance(conf, Configuration) or not identifier(conf.board)
                or conf.board in boards or not isinstance(conf.columns, tuple)
                or not conf.columns or not all(identifier(c) for c in conf.columns)
                or len(set(conf.columns)) != len(conf.columns)):
            raise ValueError('invalid_local_configuration')
        boards.add(conf.board)
    if not all(identifier(x) for x in (snapshot.expected_fingerprint, snapshot.observed_fingerprint)):
        raise ValueError('invalid_local_fingerprint')
    for flag in (snapshot.inventory_qualified, snapshot.source_types_qualified,
                 snapshot.source_access_qualified, snapshot.business_write_authorized):
        if type(flag) is not bool:
            raise ValueError('qualification_must_be_boolean')


def investigate(snapshot, approved_target=None):
    validate(snapshot, approved_target)
    by_board = {c.board: c.columns for c in snapshot.configuration}
    unknown_boards = sorted({link.board for link in snapshot.links if link.board not in by_board})
    candidates = sorted({Cell(link.board, link.item, column)
                         for link in snapshot.links
                         for column in by_board.get(link.board, ())})
    reason = None
    if not snapshot.inventory_qualified or unknown_boards:
        reason = 'source_inventory_not_qualified'
    elif snapshot.expected_fingerprint != snapshot.observed_fingerprint:
        reason = 'configuration_changed'
    elif not snapshot.source_access_qualified:
        reason = 'source_access_not_qualified'
    elif not snapshot.source_types_qualified:
        reason = 'source_type_outside_qualified_profile'
    elif snapshot.mirror in candidates:
        reason = 'mirror_returned_as_its_own_source'
    elif not candidates:
        reason = 'no_source_candidate_not_a_delete_instruction'
    elif approved_target is None:
        reason = 'multiple_sources_need_business_target' if len(candidates) > 1 else 'single_source_still_needs_business_target'
    elif approved_target == snapshot.mirror:
        reason = 'direct_mirror_value_write_not_planned'
    elif approved_target not in candidates:
        reason = 'approved_target_not_in_observed_source_candidates'
    elif not snapshot.business_write_authorized:
        reason = 'source_relation_is_not_write_authority'
    return {'decision': 'hold' if reason else 'local_target_proposal',
            'reason': reason,
            'candidates': [vars(c) for c in candidates],
            'unconfigured_source_boards': unknown_boards,
            'target': vars(approved_target) if reason is None else None,
            'native_mutation_performed': False,
            'native_permissions_certified': False,
            'remote_atomicity_certified': False}


def fictional_summary(values):
    """Toy display of values only, not monday's aggregation implementation."""
    return ', '.join(values)


def run_checks():
    names = []
    def check(name, condition):
        if name in names or not condition:
            raise AssertionError(name)
        names.append(name)

    mirror = Cell('cockpit', 'order-7', 'delivery_mirror')
    a = Cell('warehouse-a', 'shipment-11', 'delivery_status')
    b = Cell('warehouse-b', 'shipment-22', 'delivery_status')
    one = Snapshot(mirror, (Link(a.board, a.item),),
                   (Configuration(a.board, (a.column,)),), 'cfg-1', 'cfg-1')
    two = replace(one, links=one.links+(Link(b.board, b.item),),
                  configuration=one.configuration+(Configuration(b.board, (b.column,)),))
    allowed = replace(two, business_write_authorized=True)
    checks = {}
    checks['one_without_target'] = investigate(one)
    checks['two_without_target'] = investigate(two)
    checks['approved_a'] = investigate(allowed, a)
    checks['approved_b'] = investigate(allowed, b)
    check('unique_source_does_not_invent_business_target', checks['one_without_target']['reason'] == 'single_source_still_needs_business_target')
    check('multiple_sources_are_not_reduced_to_first', checks['two_without_target']['reason'] == 'multiple_sources_need_business_target')
    check('two_distinct_candidates_are_retained', len(checks['two_without_target']['candidates']) == 2)
    check('approved_a_is_exact_tuple', checks['approved_a']['target'] == vars(a))
    check('approved_b_is_exact_tuple', checks['approved_b']['target'] == vars(b))
    check('same_relation_without_business_authority_is_held', investigate(two, a)['reason'] == 'source_relation_is_not_write_authority')
    check('direct_mirror_target_is_not_a_source_write', investigate(allowed, mirror)['reason'] == 'direct_mirror_value_write_not_planned')
    check('wrong_item_is_not_selected_by_board_and_column', investigate(allowed, replace(a, item='other-item'))['reason'] == 'approved_target_not_in_observed_source_candidates')
    check('wrong_board_is_not_selected_by_item_and_column', investigate(allowed, replace(a, board='other-board'))['reason'] == 'approved_target_not_in_observed_source_candidates')
    check('wrong_column_is_not_selected_by_board_and_item', investigate(allowed, replace(a, column='invoice_status'))['reason'] == 'approved_target_not_in_observed_source_candidates')
    changed = investigate(replace(allowed, observed_fingerprint='cfg-2'), a)
    check('configuration_drift_holds_previously_approved_target', changed['reason'] == 'configuration_changed')
    check('configuration_fingerprint_does_not_mutate_source', changed['target'] is None and not changed['remote_atomicity_certified'])
    check('incomplete_inventory_holds_even_known_target', investigate(replace(allowed, inventory_qualified=False), a)['reason'] == 'source_inventory_not_qualified')
    check('unknown_link_board_is_not_silently_dropped', investigate(replace(allowed, links=allowed.links+(Link('unknown-board','known-looking-item'),)), a)['reason'] == 'source_inventory_not_qualified')
    check('source_access_is_not_inferred_from_mirror_visibility', investigate(replace(allowed, source_access_qualified=False), a)['reason'] == 'source_access_not_qualified')
    check('nested_or_unqualified_source_type_is_held', investigate(replace(allowed, source_types_qualified=False), a)['reason'] == 'source_type_outside_qualified_profile')
    empty = investigate(replace(one, links=()))
    check('empty_source_list_is_not_deletion', empty['reason'] == 'no_source_candidate_not_a_delete_instruction')
    check('empty_source_list_has_no_target', empty['target'] is None)
    multi_columns = replace(one, configuration=(Configuration(a.board, ('planned_date','actual_date')),))
    multi_result = investigate(multi_columns)
    check('two_source_columns_are_not_disambiguated_by_item_id', len(multi_result['candidates']) == 2 and multi_result['reason'] == 'multiple_sources_need_business_target')
    check('old_column_target_does_not_survive_configuration_replacement', investigate(replace(multi_columns,business_write_authorized=True),a)['reason'] == 'approved_target_not_in_observed_source_candidates')
    same_board = replace(one, links=one.links+(Link(a.board,'shipment-12'),))
    check('multiple_items_on_one_board_still_ambiguous', len(investigate(same_board)['candidates']) == 2)
    duplicate = replace(one, links=one.links+one.links)
    check('identical_link_repetition_deduplicates_exact_cell', investigate(duplicate)['candidates'] == investigate(one)['candidates'])
    self_source = replace(one, links=(Link(mirror.board,mirror.item),), configuration=(Configuration(mirror.board,(mirror.column,)),))
    check('cycle_to_mirror_is_not_rewritten_as_source', investigate(replace(self_source,business_write_authorized=True),mirror)['reason'] == 'mirror_returned_as_its_own_source')

    # Non-injectivity witness: the same displayed text belongs to two different
    # fictional source inventories. No native API response is fabricated here.
    world_a = {'cells': [vars(a)], 'values': ['Ready']}
    world_b = {'cells': [vars(b)], 'values': ['Ready']}
    summary_a = fictional_summary(world_a['values'])
    summary_b = fictional_summary(world_b['values'])
    check('distinct_worlds_have_identical_toy_summary', summary_a == summary_b == 'Ready' and world_a['cells'] != world_b['cells'])
    one_b = replace(one, links=(Link(b.board,b.item),), configuration=(Configuration(b.board,(b.column,)),))
    check('same_summary_does_not_produce_same_source_inventory', investigate(one)['candidates'] != investigate(one_b)['candidates'])
    check('neither_summary_only_world_grants_write_authority', investigate(one)['target'] is None and investigate(one_b)['target'] is None)
    for n, links in enumerate(permutations(allowed.links),1):
        for k, config in enumerate(permutations(allowed.configuration),1):
            value=investigate(replace(allowed,links=links,configuration=config),b)
            check('source_order_independent_'+str(n)+'_'+str(k), value == checks['approved_b'])
    for flag in ('inventory_qualified','source_types_qualified','source_access_qualified','business_write_authorized'):
        invalid=replace(allowed,**{flag:1});rejected=False
        try:investigate(invalid,a)
        except ValueError:rejected=True
        check('non_boolean_'+flag+'_rejected',rejected)
    invalid_cases=[replace(one,links=list(one.links)),replace(one,configuration=list(one.configuration)),
                   replace(one,links=(Link(True,a.item),)),replace(one,mirror=Cell('',mirror.item,mirror.column)),
                   replace(one,configuration=(Configuration(a.board,(a.column,a.column)),)),
                   replace(one,configuration=one.configuration+one.configuration),
                   replace(one,configuration=(Configuration(a.board,()),)),replace(one,observed_fingerprint=' cfg-1')]
    for n, case in enumerate(invalid_cases,1):
        rejected=False
        try:investigate(case,a)
        except ValueError:rejected=True
        check('invalid_local_inventory_'+str(n),rejected)
    check('input_snapshot_not_modified', one.links == (Link(a.board,a.item),) and not one.business_write_authorized)
    check('all_examples_have_zero_native_mutations', all(not v['native_mutation_performed'] for v in checks.values()))
    return {'checks_passed':len(names),'check_names':names,'python_version':sys.version,
            'examples':checks,'summary_collision':{'world_a':world_a,'world_b':world_b,'same_toy_display':summary_a},
            'scope':{'http_calls':0,'monday_mutations':0,'erp_operations':0,'persistent_writes':0,
                     'native_response_parser':False,'native_permissions_certified':False,'remote_atomicity_certified':False,
                     'summary_is_fictional_not_native_renderer':True,'candidate_enumeration_actually_executed':True}}


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