"""Bridge-derivability test for the dual of Holton-McKay's Fig. 2.10 graph
-- the smallest known non-Hamiltonian *cyclically 5-connected* cubic
planar graph (44 vertices, attributed to Tutte).

We obtain the graph by generation rather than transcription. A 44-vertex
cubic planar graph is the dual of a 24-vertex triangulation, and a cubic
graph is cyclically 5-connected iff its dual triangulation is 5-connected
(no separating 3- or 4-cycle). So we run

    plantri -c5 -d -g 24

to list every 5-connected 24-vertex triangulation's cubic dual, keep the
non-Hamiltonian ones (Hamiltonicity of the dual = intertwining-tree of the
triangulation, by the paper's equivalence), and test each resulting
triangulation T = dual(H) for bridge-derivability. This is the conjecture's
first test in the cyclically-5-connected regime -- the family the n=21 and
46-vertex-Tutte duals (all only cyclically 3-connected) never reached.

Run after /tmp/nonham_duals.g6 has been produced by the Hamiltonicity
filter (lines: "<index> <graph6>").
"""
import sys
import os
import time
sys.path.insert(0, '/Users/didericis/Code/math-research/papers/'
                'level_resolutions_of_maximal_planar_graphs/experiments')
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import networkx as nx
from sage.all import Graph  # type: ignore
from tutte_dual_treecolor import dual_triangulation
from fast_bridge import EdgeCode
from test_tutte_bridge import (
    characterize, valid_parity_partitions_via_coloring, search_partition,
)


def sage_to_nx(G):
    H = nx.Graph()
    H.add_nodes_from(int(v) for v in G.vertices())
    H.add_edges_from((int(u), int(v)) for u, v in G.edges(labels=False))
    return H


def test_one(g6, cap=600_000, time_limit=180.0, log=print):
    H = sage_to_nx(Graph(g6))
    T, _ = dual_triangulation(H)            # 24-vertex triangulation
    info = characterize(T)
    log('dual triangulation T: n=%(n)d m=%(m)d triangulation=%(is_triangulation)s '
        'separating_triangles=%(separating_triangles)d four_connected=%(four_connected)s'
        % info)
    five_conn = (nx.node_connectivity(T) >= 5)
    log('  vertex-connectivity(T) >= 5: %s   [cyclically-5-connected cubic dual]'
        % five_conn)

    code = EdgeCode(T.nodes())
    code.state0 = code.state_of(T)
    n = info['n']
    parts, n_col = valid_parity_partitions_via_coloring(T)
    log('  %d valid parity partitions (from %d 4-colorings)' % (len(parts), n_col))

    t0 = time.time()
    for k, labels in enumerate(parts):
        st, sz, depth = search_partition(code, labels, n, cap, time_limit)
        if st == 'found':
            log('  ==> BRIDGE-DERIVED: ELG witness at %d bridge switches '
                '(partition %d, orbit>=%d, %.0fs)' % (depth, k, sz, time.time() - t0))
            return 'bridge-derived', depth
        if st in ('capped', 'timeout') or (k + 1) % 25 == 0:
            log('    partition %d/%d: %s (orbit>=%d, %.0fs)'
                % (k + 1, len(parts), st, sz, time.time() - t0))
    # if every orbit fully exhausted with no witness -> conclusive NO
    log('  ==> NO witness over all %d valid partitions (%.0fs)'
        % (len(parts), time.time() - t0))
    return 'no-witness', None


def main():
    path = '/tmp/nonham_duals.g6'
    rows = []
    with open(path) as f:
        for line in f:
            line = line.strip()
            if line:
                idx, g6 = line.split(None, 1)
                rows.append((int(idx), g6))
    print('%d non-Hamiltonian cyclically-5-connected 44-vertex duals to test\n'
          % len(rows), flush=True)
    for idx, g6 in rows:
        print('### candidate (plantri index %d): %s' % (idx, g6), flush=True)
        verdict, depth = test_one(g6)
        print('### verdict: %s\n' % verdict, flush=True)


if __name__ == '__main__':
    main()
