#!/bin/env jython
import json
import sys

import org.gavrog


def run():
    def writeln(s=''):
        print s

    for source_path in sys.argv[1:]:
        index_in_source = 0

        for net in org.gavrog.joss.pgraphs.io.Net.iterator(source_path):
            index_in_source += 1

            writeln('{')
            writeln('  "source_path": "%s",' % source_path)
            writeln('  "index_in_source": %d,' % index_in_source)

            warnings, errors = process_net(net, writeln=writeln)
            status = "Error" if errors else "OK"

            writeln('  "warnings": %s,' % json.dumps(warnings))
            writeln('  "errors": %s,' % json.dumps(errors))
            writeln('  "status": "%s"' % status)
            writeln('}')
            writeln()


def process_net(net, writeln):
    writeln('  "net_name": "%s",' % net.name)

    warnings = list(net.warnings)
    errors = list(net.errors)

    if errors:
        return warnings, errors

    if not net.isConnected():
        errors.append("disconnected net")
    elif not net.isStable():
        warnings.append("net has collisions")

        if not net.isLocallyStable():
            errors.append("next-nearest neighbor collisions")
        elif net.isLadder():
            errors.append("ladder net")
        elif net.hasSecondOrderCollisions():
            errors.append("possible ladder net")

    if errors:
        return warnings, errors

    if not net.isMinimal():
        warnings.append("reduced from supercell")

    minmap = net.minimalImageMap()
    net = minmap.imageGraph
    name_for_node, merged_names = node_name_mapping(minmap)

    finder = org.gavrog.joss.geometry.SpaceGroupFinder(net.getSpaceGroup())
    writeln('  "spacegroup_name": "%s",' % finder.groupName)

    if finder.extension:
        writeln('  "spacegroup_extension": "%s",' % finder.extension)

    return warnings, errors


def node_name_mapping(phi):
    orbit_for_image_node = {}
    for orbit in phi.imageGraph.nodeOrbits():
        orbit = frozenset(orbit)
        for v in orbit:
            orbit_for_image_node[v] = orbit

    name_for_orbit = {}
    name_for_node = {}
    merged_names = []
    merged_names_seen = set()

    for v in phi.sourceGraph.nodes():
        name = phi.sourceGraph.getNodeName(v)
        w = phi.getImage(v)
        orbit = orbit_for_image_node[w]

        if name != name_for_orbit.get(orbit, name):
            pair = (name, name_for_orbit[orbit])
            if pair not in merged_names_seen:
                merged_names.append(pair)
                merged_names_seen.add(pair)
        else:
            name_for_orbit[orbit] = name

        name_for_node[w] = name_for_orbit[orbit]

    return name_for_node, merged_names


if __name__ == "__main__":
    run()

@@ -1502,22 +1502,19 @@
 %22)%0A%0A    
-minmap
+net
  = net.m
@@ -1528,100 +1528,9 @@
 mage
-Map()%0A    net = minmap.imageGraph%0A    name_for_node, merged_names = node_name_mapping(minmap
+(
 )%0A%0A 
@@ -1661,25 +1661,24 @@
 .groupName)%0A
-%0A
     if finde
@@ -1769,103 +1769,42 @@
     
-return warnings, errors%0A%0A%0Adef node_name_mapping(phi):%0A    orbit_for_image_node = %7B%7D%0A   
+orbit_reps = %5Blist(orb)%5B0%5D
  for orb
 it i
@@ -1803,28 +1803,15 @@
  orb
-it
  in 
-phi.imageGraph
+net
 .nod
@@ -1823,742 +1823,612 @@
 ts()
-:
+%5D
 %0A    
-    orbit = frozenset(orbit)%0A        for v in orbit:%0A            orbit_for_image_node%5Bv%5D = orbit%0A%0A    name_for_orbit = %7B%7D%0A    name_for_node = %7B%7D%0A    merged_names = %5B%5D%0A    merged_names_seen = set()%0A%0A    for v in phi.sourceGraph.nodes():%0A        name = phi.sourceGraph.getNodeName(v)%0A        w = phi.getImage(v)%0A        orbit = orbit_for_image_node%5Bw%5D%0A%0A        if name != name_for_orbit.get(orbit, name):%0A            pair = (name, name_for_orbit%5Borbit%5D)%0A            if pair not in merged_names_seen:%0A                merged_names.append(pair)%0A                merged_names_seen.add(pair)%0A        else:%0A            name_for_orbit%5Borbit%5D = name%0A%0A        name_for_node%5Bw%5D = name_for_orbit%5Borbit%5D%0A%0A    return name_for_node, merged_names
+seqs = %5Bcoordination_sequence(net, v, 10) for v in orbit_reps%5D%0A%0A    writeln('  %22net_nodes_unitcell%22: %25s,' %25 net.numberOfNodes())%0A    writeln('  %22net_nodes_asym%22: %25s,' %25 len(orbit_reps))%0A%0A    writeln('  %22net_valency%22: %25s,' %25 json.dumps(%5Bs%5B0%5D for s in seqs%5D))%0A    writeln('  %22net_coordination_seqs%22: %5B')%0A    writeln('      %25s' %25 ',%5Cn      '.join(json.dumps(s) for s in seqs))%0A    writeln('    %5D,')%0A%0A    return warnings, errors%0A%0A%0Adef coordination_sequence(net, v, n):%0A    cs = net.coordinationSequence(v)%0A    cs.next()%0A%0A    out = %5B%5D%0A    for i in range(n):%0A        out.append(cs.next())%0A%0A    return out
 %0A%0A%0Ai

add vertex counts, valencies, coordination seqs