/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package org.biohackathon.SPARQLBuilder.OWL;

import java.io.*;
import java.util.*;

/**
 *
 * @author atsuko
 */

public class QueryPathGenerator {
    private RDFSchemaAnalyzerFactory factory = null;
    RDFSchemaAnalyzer analyzer = null;
    private OWLClassGraph graph;

    private Map<String, String> clabels;
    
    private static final String CDIR = "cdata";
    private static final String ODIR = "owldata";
    
    public QueryPathGenerator(){
        factory = new RDFSchemaAnalyzerFactory(CDIR);
        try{
            analyzer = factory.create();
        }catch(Exception e){
            System.err.println(e);            
        }
    }

    public SClass[] getClasses(){
        return getClassList().toArray(new SClass[0]);
    }

    public List<SClass> getClassList(){
        List<SClass> cl = null;
        try {
            cl = new LinkedList<SClass>(analyzer.getOWLClassList(null, null));
        }catch(Exception e){
            System.err.println(e);
            return null;
        }
        return cl;
    }     
    
    public Path[] getPaths(String startClass, String endClass){
        if (startClass == null || endClass == null){
            return null;
        }
        if ( graph == null ){
            //setOWLClassGraph(startClass);
        }
        return graph.getPaths(startClass, endClass);
    }
    
    public RDFSchemaAnalyzerFactory getFactory(){
        return factory;
    }
    
    public String getClassLabel(String classURI){
        return clabels.get(classURI);
    }
    
    public void setClassLabels(SClass[] classes){
        clabels = new HashMap<String, String>();
        Map<String, String> extLabels = getClassLabelsFromExternal();
        
        for ( int i = 0 ; i < classes.length; i++ ){
            String classURI = classes[i].getClassURI();

            Label[] labels = classes[i].getLabels();
            String label = null;
            for ( int j = 0 ; j < labels.length; j++ ){
                if ( labels[j].getLanguage() == null ){
                    label = labels[j].getLabel(); 
                    break;
                }else if ( labels[j].getLanguage().equals("en") || labels[j].getLanguage().equals("") ){
                    label = labels[j].getLabel(); 
                    break;
                }
            }
            if ( label == null ){
                label = extLabels.get(classURI);
            }
            if ( label == null ){
                String[] uris = classURI.split("/");
                String tmplabel = uris[uris.length-1];
                String[] tmplabel2 = tmplabel.split("#");
                label = tmplabel2[tmplabel2.length-1];
            }
            clabels.put(classURI, label);
        }
    }

    public static String getClassLabelfromList(String classURI, SClass[] classes){
        if ( classURI == null ){
                    return "";
        }
        SClass sclass = null;
        for ( int i = 0 ; i < classes.length; i++ ){
            if ( classURI.equals(classes[i].getClassURI()) ){
                return getClassLabelfromClass(classes[i]);
            }
        }
        return "";
    }
    
    public static String getClassLabelfromClass(SClass sclass){
        Label[] labels = sclass.getLabels();
        for ( int i = 0 ; i < labels.length; i++ ){
            if ( labels[i].getLanguage() == null ){
                return labels[i].getLabel();
            }else if ( labels[i].getLanguage().equals("en") ){
                return labels[i].getLabel();
            }
        }
        String[] url = sclass.getClassURI().split("/");
        String tmplabel = url[url.length-1];
        String[] tmplabel2 = tmplabel.split("#");
        String label = tmplabel2[tmplabel2.length-1];
        return label;
    }
        
    public Map<String, String> getClassLabelsFromExternal(){
        return  OWLLabelReader.readLabels(ODIR);
    }
    
    public OWLClassGraph getOWLClassGraph(){
        /*if ( graph == null ){
            graph = new OWLClassGraph(analyzer);             
        }*/
        return graph;
    }
    
    /*
    public SClass[] getReachableClasses(){
        List<String> clURIs = graph.getReachableClasses();
        SClass[] orgclasses = null;
        try {
            orgclasses = analyzer.getOWLClasses(null, null, null, true);
        }catch( Exception e ){
            System.err.println(e);
            return null;
        }
        HashMap<String, SClass> orgmap = new HashMap<String, SClass>();
        for (int i = 0; i < orgclasses.length; i++ ){
            orgmap.put(orgclasses[i].getClassURI(), orgclasses[i]);
        }
        
        SClass[] classes = new SClass[clURIs.size()];
        int j = 0;
        ListIterator<String> uit = clURIs.listIterator();
        while(uit.hasNext()){
            String u = uit.next();
            SClass cl = orgmap.get(u);
            classes[j] = cl;
            j++;
        }
        return classes;
    }
    */
    
    public SortedSet<String> getSortedClasses(SClass[] classes){
        setClassLabels(classes);
        SortedSet<String> sortedClasses = new TreeSet<String>();
        for (int i = 0 ; i < classes.length; i++ ){
            String uri = classes[i].getClassURI();
            String label = getClassLabel(uri);
            StringBuilder classbuilder = new StringBuilder(label);
            classbuilder.append("\t");
            classbuilder.append(classes[i].getNumOfInstances());
            classbuilder.append("\t");
            classbuilder.append(uri);
            sortedClasses.add(classbuilder.toString());
        }

        return sortedClasses;
    }
}
