package eu.dnetlib.data.collective.transformation.core.schema;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;

import org.xml.sax.SAXException;

import com.sun.xml.xsom.XSContentType;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSParticle;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSTerm;
import com.sun.xml.xsom.parser.XSOMParser;

import eu.dnetlib.data.collective.transformation.core.schema.visitor.Visitor;

/**
 * @author jochen
 *
 */
public class SchemaInspector {

	private List<SchemaElement> elementList = new java.util.LinkedList<SchemaElement>();
	private boolean inspected = false;
	private String rootElement;

	public void inspect(File aSchema, String aRootElement) throws SAXException, IOException{
		XSOMParser parser = new  XSOMParser();
		parser.parse(aSchema);		
		doInspect(parser, aRootElement);
	}
	
	public void inspect(URL aSchema, String aRootElement)throws SAXException{
		XSOMParser parser = new  XSOMParser();
		parser.parse(aSchema);
		doInspect(parser, aRootElement);
	}
	
	/**
	 * inspects the schema and creates a new list of schema elements.
	 * @param parser
	 * @param aRootElement
	 * @throws SAXException
	 */
	private void doInspect(XSOMParser parser, String aRootElement) throws SAXException{
		this.rootElement = aRootElement;
//		for (SchemaDocument doc: parser.getDocuments()){
//			Map<String, XSAttributeDecl> attgrdecls = doc.getSchema().getAttributeDecls();
//			for (String k: attgrdecls.keySet()){
//				System.out.println("keyxs: " + k);
//			}
//		}
		Visitor visitor = new Visitor();
		XSSchemaSet sset = parser.getResult();
//		Iterator<XSAttributeDecl> it = sset.iterateAttributeDecls();
//		while(it.hasNext()){
//			System.out.println(it.next().getName());
//		}
		XSElementDecl elemDecl = sset.getElementDecl("", aRootElement);
		if (elemDecl == null){
			throw new IllegalStateException("rootElement " + aRootElement + " not found in schema.");
		}
		// assuming the root element is of complex type
		if (elemDecl.getType().isComplexType()){
			XSContentType contentType = elemDecl.getType().asComplexType().getContentType();				
			XSParticle particle = contentType.asParticle();
			if (particle != null){
				XSTerm term = particle.getTerm();
				term.visit(visitor);
			}
		}
		this.elementList = visitor.getElements();
		this.inspected = true;		
	}
	
	/**
	 * @return the inspected
	 */
	public boolean isInspected() {
		return inspected;
	}

	/**
	 * @return the rootElement
	 */
	public String getRootElement() {
		return rootElement;
	}
	
	/**
	 * @return the child elements
	 */
	public List<SchemaElement> getChildElements(){
		return elementList;
	}
}
