
import java.io.File;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnnotation;
import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyManager;

import static org.semanticweb.owlapi.search.Searcher.annotations;


public class ReadOwl {
	public static final IRI hasExactSynonym = IRI.create("http://www.geneontology.org/formats/oboInOwl#hasExactSynonym");
	public static final IRI hasRelatedSynonym = IRI.create("http://www.geneontology.org/formats/oboInOwl#hasRelatedSynonym");
	
	public static List<Map.Entry<String, String>> loadReference(File referenceFile) throws Exception {
		OWLOntologyManager m = OWLManager.createOWLOntologyManager();
		OWLOntology o = m.loadOntologyFromOntologyDocument(referenceFile);
		if(o == null) throw new Exception("Ontology error");
		
		HashMap<String, String> entity1 = new HashMap<>();
		HashMap<String, String> entity2 = new HashMap<>();
		for(OWLAxiom ax : o.getAxioms()) {
			if(ax.getAxiomType().toString().equals("AnnotationAssertion")) {
				OWLAnnotationAssertionAxiom aax = (OWLAnnotationAssertionAxiom) ax;
				OWLAnnotation annot = aax.getAnnotation();
				if(annot.getProperty().toString().equals("<http://knowledgeweb.semanticweb.org/heterogeneity/alignmententity1>")) {
					entity1.put(aax.getSubject().toString(), aax.getValue().toString());
				} else if(annot.getProperty().toString().equals("<http://knowledgeweb.semanticweb.org/heterogeneity/alignmententity2>")) {
					entity2.put(aax.getSubject().toString(), aax.getValue().toString());
				}
			}
		}
		List<Map.Entry<String, String>> result = new ArrayList<>();
		for(String key : entity1.keySet()) {
			String e1 = entity1.get(key);
			String e2 = entity2.get(key);
			if(e1 == null || e2 == null) {
				continue;
			}
			result.add(new AbstractMap.SimpleEntry<>(e1, e2));
		}
		return result;
	}
	
	
	public static Map<String, List<String>> loadConcepts(File ontologySrc) throws Exception {
		OWLOntologyManager m = OWLManager.createOWLOntologyManager();
		OWLOntology o = m.loadOntologyFromOntologyDocument(ontologySrc);
		if(o == null) throw new Exception("Ontology parsing error");
		Map<String, List<String>> concepts = new HashMap<>();
		// Create Concepts
		for(OWLClass cls : o.getClassesInSignature()) {
			String iri = cls.getIRI().toString();
			List<String> labels = new ArrayList<>();
			if(iri == null) continue;
			for(OWLAnnotation anno : annotations(o.getAnnotationAssertionAxioms(cls.getIRI()))) {
				OWLAnnotationProperty prop = anno.getProperty();
				if(anno.getValue() instanceof OWLLiteral) {
					OWLLiteral lit = (OWLLiteral) anno.getValue();
					if(prop.isLabel()) {
						labels.add(lit.getLiteral().toLowerCase().replaceAll("[^a-z0-9]", ""));
					} else {
						// other optional infos
					}
				} else {
					// other optional infos
				}
			}
			concepts.put(iri, labels);
		}
		return concepts;
	}
	
	public static boolean contains(List<Map.Entry<String, String>> result, String s1, String s2) {
		for(Map.Entry<String, String> entry : result) {
			if(entry.getKey().equals(s1) && entry.getValue().equals(s2)) return true;
		}
		return false;
	}
	
	public static void main(String[] args) throws Exception {
		Map<String, List<String>> concepts1 = loadConcepts(new File("../anatomy-dataset/mouse.owl"));
		Map<String, List<String>> concepts2 = loadConcepts(new File("../anatomy-dataset/human.owl"));
		List<Map.Entry<String, String>> references = loadReference(new File("../anatomy-dataset/reference.rdf"));
		
// 		int hits = 0;
// 		int mishits = 0;
// 		
// 		for(String k1 : concepts1.keySet()) {
// 			for(String k2 : concepts2.keySet()) {
// 				(...)
	}
}
