package eu.dnetlib.data.textengine.categorizer;

import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;

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

	private static final Log log = LogFactory.getLog(VocabularyMapper.class);
	private static final String vocabResourceFile = "driver_lang_vocab.xml";
	private static final String vocabResourceXQuery = "collection('/db/DRIVER/VocabularyDSResources/VocabularyDSResourceType')//RESOURCE_PROFILE[.//VOCABULARY_NAME = 'Names of Languages']/BODY/CONFIGURATION/TERMS";
	
	private ISLookUpService lookupService;
	private Map<String, String> iso632_2Table = new HashMap<String, String>();
	
	public void init(){
		SAXReader reader = new SAXReader();
		Document doc = null;
		String resource = null;
		try {
			
			if (lookupService == null){
				// try loading local map
				InputStream inStream = this.getClass().getClassLoader().getResourceAsStream(vocabResourceFile);
				try {
					doc = reader.read(inStream);
				} catch (DocumentException e) {
					log.error(e);
				}
			}else if ((resource = lookupService.getResourceProfileByQuery(vocabResourceXQuery)) != null){
					doc = reader.read(new StringReader(resource));
			}else{
				InputStream inStream = this.getClass().getClassLoader().getResourceAsStream(vocabResourceFile);
				try {
					doc = reader.read(inStream);
				} catch (DocumentException e) {
					log.error(e);
				}
			}		
		
			parse(doc);		
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ISLookUpDocumentNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ISLookUpException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}			
	}
	
	public void updateMapping(String resource){
		SAXReader reader = new SAXReader();
		Document doc = null;
		try {
			doc = reader.read(new StringReader(resource));
		} catch (DocumentException e) {
			log.error(e);
		}		
		parse(doc);		
	}
	
	@SuppressWarnings("unchecked")
	private void parse(Document doc){
		XPath xpath =  doc.createXPath("//TERM/@encoding");
		List<Node> list = xpath.selectNodes(doc);
		for (Node n: list){
			String iso632_2Code = ((Attribute)n).getValue();
			for(String isoCode: iso632_2Code.split("/")){
				iso632_2Table.put(isoCode, iso632_2Code);
			}
		}		
	}
	
	public Map<String, String> getMapping(){
		return iso632_2Table;
	}

	/**
	 * @param lookupService the lookupService to set
	 */
	public void setLookupService(ISLookUpService lookupService) {
		this.lookupService = lookupService;
	}

	/**
	 * @return the lookupService
	 */
	public ISLookUpService getLookupService() {
		return lookupService;
	}
}
