package org.arachb.owlbuilder.lib;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.arachb.arachadmin.IndividualBean;
import org.arachb.arachadmin.NarrativeBean;
import org.arachb.arachadmin.PublicationBean;
import org.arachb.arachadmin.TermBean;
import org.arachb.owlbuilder.Owlbuilder;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnnotation;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLObject;

public class Individual implements NamedGeneratingEntity{

	private static Logger log = Logger.getLogger(Individual.class);

	
	private final IndividualBean bean;
	
	
	
	public Individual(IndividualBean ib){
		bean = ib;
	}
	
	
	private final Map<String, OWLObject> localElements = new HashMap<>();
	
	
	@Override	
	public OWLObject generateOWL(Owlbuilder b) throws Exception{
		OWLObject result = generateOWL(b,localElements);
		localElements.clear();
		return result;
	}

	@Override
	public OWLObject generateOWL(Owlbuilder builder, Map<String, OWLObject> elements) throws Exception {
		final OWLDataFactory factory = builder.getDataFactory();
		IRI individualIRI;
			try {
				String indString = bean.checkIRIString(builder.getIRIManager());
				if (elements.containsKey(indString)){
					return elements.get(indString);
				}
				individualIRI = IRI.create(indString);
				OWLIndividual namedIndividual = factory.getOWLNamedIndividual(individualIRI);
				builder.initializeMiscIndividual(namedIndividual);
				final String label = getLabelFromNarrativeSet();
				if (label != null){
					log.info("Individual Bean " + indString + " has label " + label);
					OWLAnnotation labelAnno = factory.getOWLAnnotation(factory.getRDFSLabel(),
																	   factory.getOWLLiteral(label));
					OWLAxiom ax = factory.getOWLAnnotationAssertionAxiom(individualIRI, labelAnno);
					// Add the axiom to the ontology
					builder.getOntologyManager().addAxiom(builder.getTarget(),ax);
				}
				ClassTerm ct;
				if (TermBean.isCached(bean.getTerm())){
					ct =  new ClassTerm(TermBean.getCached(bean.getTerm()));
				}
				else {
					throw new RuntimeException("Term " + bean.getTerm() + " for individual " + bean.getId() + " is not cached");
				}
				OWLClass cl = (OWLClass)ct.generateOWL(builder, elements);
				OWLClassAssertionAxiom clAssertion = factory.getOWLClassAssertionAxiom(cl, namedIndividual);
				builder.getOntologyManager().addAxiom(builder.getTarget(), clAssertion);
				builder.initializeMiscIndividual(namedIndividual);
				elements.put(indString, namedIndividual);
				return namedIndividual;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return null;
			}
	}
	
	private String getLabelFromNarrativeSet(){
		switch (bean.getNaratives().size()){
		case 0: return bean.getLabel();
		case 1: Set<Integer>nSet = bean.getNaratives();
				int narrativeId = nSet.iterator().next();
				NarrativeBean narrative = NarrativeBean.getCached(narrativeId);
				return labelFromNarrative(narrative);
		default:
			return bean.getLabel() + " in multiple narratives";
		}
	}
	
	private String labelFromNarrative(NarrativeBean n){
		log.info("publication cache size = " + PublicationBean.cacheSize());
		PublicationBean p = PublicationBean.getCached(n.getPublicationId());
		String pubStr = p.getAuthorList()+"("+p.getPublicationYear()+")";
		return bean.getLabel() + " in " + n.getLabel() + " contained in " + pubStr;
	}
	

	/* methods to expose bean fields */
	
}

@@ -770,16 +770,72 @@
 LObject;
+%0Aimport org.semanticweb.owlapi.model.OWLOntologyManager;
 %0A%0Apublic
@@ -1474,16 +1474,83 @@
 tory();%0A
+%09%09final OWLOntologyManager manager = builder.getOntologyManager();%0A
 %09%09IRI in
@@ -2316,36 +2316,416 @@
 %09%09%09%09
-builder.getOntologyManager()
+manager.addAxiom(builder.getTarget(),ax);%0A%09%09%09%09%7D%0A%09%09%09%09final String iComment = %22Individual from individual owlgeneration, id = %22 + bean.getId();%0A%09%09%09%09OWLAnnotation commentAnno = factory.getOWLAnnotation(factory.getRDFSComment(), %0A%09%09%09%09%09%09                                             factory.getOWLLiteral(iComment));%0A%09%09%09%09OWLAxiom ax = factory.getOWLAnnotationAssertionAxiom(individualIRI, commentAnno);%0A%09%09%09%09manager
 .add
@@ -2751,30 +2751,24 @@
 rget(),ax);%0A
-%09%09%09%09%7D%0A
 %09%09%09%09ClassTer
@@ -4284,13 +4284,78 @@
 ields */
+%0A%0A%09public String getIRIString()%7B%0A%09%09return bean.getIRIString();%0A%09%7D
 %0A%09%0A%7D%0A

add rdfs:comment to Individual and getIRIString() pass through method