"""Attempt to construct a level-d pinch in a maximal planar graph.

Construction:
  v_0 at center, pentagon a_1, ..., a_5 around v_0.
  Outside the pentagon, vertex v adjacent to a_1, a_3 (non-adjacent
  pentagon vertices).  The "lobe" between v and the pentagon edge
  a_1-a_2-a_3 contains a_2 and is triangulated by adding vertex x
  in the lobe, x adjacent to a_1, a_2, a_3, v.  On the OTHER side of
  v (outside the V formed by edges v-a_1, v-a_3), we triangulate by
  adding w_1 adjacent to a_1, a_3, a_4, a_5, v.

Vertex labels:
  0 = v_0 (source)
  1..5 = a_1..a_5 (pentagon, level 1)
  6 = v   (level 2)
  7 = x   (level 2)
  8 = w_1 (level 2)

If this is planar and is a maximal planar graph, then v has level-1
neighbours a_1=1, a_3=3 in DIFFERENT arcs of v's rotation, separated
by level-2 neighbours x=7 on the lobe side and w_1=8 on the outer side.
This would be a level-d (d=2) pinch.
"""
import os
import sys
from collections import defaultdict
from sage.all import Graph

EDGES = [
    (0, 1), (0, 2), (0, 3), (0, 4), (0, 5),
    (1, 2), (2, 3), (3, 4), (4, 5), (5, 1),
    (6, 1), (6, 3), (6, 7), (6, 8),
    (7, 1), (7, 2), (7, 3),
    (8, 1), (8, 3), (8, 5), (8, 4),
]


def main():
    G = Graph(EDGES)
    print(f"n = {G.order()}, m = {G.size()}")
    print(f"Max planar would need m = 3n - 6 = {3 * G.order() - 6}")
    print(f"Planar: {G.is_planar()}")
    if not G.is_planar():
        print("Not planar -- construction failed.")
        return

    G.is_planar(set_embedding=True)
    emb = G.get_embedding()
    print(f"Rotation around v=6: {emb[6]}")

    dist = G.shortest_path_lengths(0)
    print(f"BFS distances from source v_0=0: {dict(dist)}")
    print()

    # Pretty-print rotation of vertex 6 with levels
    rot_6 = emb[6]
    print(f"v=6's rotation in Pi_G: {rot_6}")
    print(f"  levels:          {[dist[u] for u in rot_6]}")

    # Check faces around vertex 6
    faces = G.faces(embedding=emb)
    faces_at_6 = []
    for f in faces:
        verts = [e[0] for e in f]
        if 6 in verts:
            d = min(dist[v] for v in verts)
            faces_at_6.append((verts, d))
    print(f"\nFaces at vertex 6:")
    for f, d in faces_at_6:
        print(f"  {f}  depth={d}")

    # Check the depth-(d-1=1)? No, we want vertex 6 at level 2.
    # We're checking: vertex 6 (level 2) with level-1 neighbors {1, 3}.
    # Are they in the same arc of vertex 6's rotation?
    level1_nbrs = [u for u in rot_6 if dist[u] == 1]
    print(f"\nLevel-1 neighbours of v=6: {level1_nbrs}")
    if len(level1_nbrs) > 1:
        # Find arcs
        positions = [i for i, u in enumerate(rot_6) if dist[u] == 1]
        print(f"  positions in rotation: {positions}")
        # Are they contiguous?  Count runs
        in_l1 = [dist[u] == 1 for u in rot_6]
        n_runs = sum(1 for i in range(len(in_l1))
                     if in_l1[i] and not in_l1[(i - 1) % len(in_l1)])
        print(f"  number of arcs of level-1 neighbours: {n_runs}")
        if n_runs > 1:
            print("  ==> LEVEL-d PINCH!  Counterexample constructed.")
        else:
            print("  ==> single contiguous arc.  No pinch.")


if __name__ == '__main__':
    main()
