package org.slc.sli.validation.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import org.slc.sli.validation.NeutralSchemaFactory;
import org.slc.sli.validation.schema.NeutralSchema;

/**
 * Utility class for exporting Neutral Schema files to flat files.
 * 
 * @author Ryan Farris <rfarris@wgen.net>
 * 
 */
public class NeutralJsonExporter {
    
    /**
     * Loads the XSD files and dumps the Neutral Schema objects to JSON files in the specified
     * directory.
     * 
     * Param 1: xsdDirectory (defaults to "classpath:xliXsd")
     * Param 2: outputDir (defaults to "neutral-schemas")
     * 
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        String xsdPath = "classpath:sliXsd-wip";
        String outputDir = "neutral-schemas";
        if (args.length == 2) {
            xsdPath = args[0];
            outputDir = args[1];
        }
        
        ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
                new String[] { "spring/neutral-json-exporter-config.xml" });
        
        XsdToNeutralSchemaRepo repo = new XsdToNeutralSchemaRepo(xsdPath, new NeutralSchemaFactory());
        repo.setApplicationContext(appContext);
        
        File enumDir = new File(outputDir, "enums");
        File primitiveDir = new File(outputDir, "primitive");
        File complexDir = new File(outputDir, "complexDir");
        
        enumDir.mkdirs();
        primitiveDir.mkdirs();
        complexDir.mkdirs();
        
        List<NeutralSchema> schemas = repo.getSchemas();
        for (NeutralSchema ns : schemas) {
            if (ns.isSimple() && !ns.isPrimitive()) {
                writeSchema(enumDir, ns);
            } else if (ns.isPrimitive()) {
                writeSchema(primitiveDir, ns);
            } else {
                writeSchema(complexDir, ns);
            }
        }
    }
    
    private static void writeSchema(File dir, NeutralSchema schema) throws IOException {
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter(new File(dir, schema.getType() + ".json")));
            writer.write(schema.toJson());
            writer.flush();
        } finally {
            writer.close();
        }
    }
}

@@ -160,14 +160,147 @@
 til.
-List;%0A
+HashSet;%0Aimport java.util.List;%0Aimport java.util.Map.Entry;%0Aimport java.util.Set;%0A%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0Aimp
@@ -416,32 +416,81 @@
 lSchemaFactory;%0A
+import org.slc.sli.validation.NeutralSchemaType;%0A
 import org.slc.s
@@ -687,24 +687,119 @@
 rter %7B%0A    %0A
+    private static final Logger LOG = LoggerFactory.getLogger(NeutralJsonExporter.class);%0A    %0A
     /**%0A    
@@ -2038,24 +2038,1175 @@
 tSchemas();%0A
+        %0A        // sanity check consistency%0A        Set%3CString%3E schemaNames = new HashSet%3CString%3E();%0A        for (NeutralSchema ns : schemas) %7B%0A            schemaNames.add(ns.getType());%0A        %7D%0A        boolean sane = true;%0A        for (NeutralSchema ns : schemas) %7B%0A            for (Entry%3CString, Object%3E entry : ns.getFields().entrySet()) %7B%0A                Object obj = entry.getValue();%0A                if (obj instanceof NeutralSchema) %7B%0A                    NeutralSchema field = (NeutralSchema) obj;%0A                    if (!schemaNames.contains(field.getType()) && NeutralSchemaType.findByName(field.getType()) == null) %7B%0A                        sane = false;%0A                        LOG.error(%22Missing schema for field: %22 + ns.getType() + %22.%22 + entry.getKey() + %22%5B%22%0A                                + field.getType() + %22%5D%22);%0A                    %7D%0A                %7D else %7B%0A                    sane = false;%0A                    LOG.error(%22Unknown field type: %22 + obj.getClass().getCanonicalName());%0A                %7D%0A            %7D%0A        %7D%0A        if (!sane) %7B%0A            throw new RuntimeException(%22Sanity check failed%22);%0A        %7D%0A        %0A
         for 

add sanity checking to ensure all dependencies exist