package jp.ac.osaka_u.sparql;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.arnx.jsonic.JSON;

import com.hp.hpl.jena.rdf.model.RDFNode;

import jp.ac.osaka_u.sanken.sparql.EndpointSettings;
import jp.ac.osaka_u.sanken.sparql.SparqlAccessor;
import jp.ac.osaka_u.sanken.sparql.SparqlAccessorFactory;
import jp.ac.osaka_u.sanken.sparql.SparqlResultSet;

/**
 * Servlet implementation class FindByQuery
 */
public class FindByQuery extends SparqlServletBase {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FindByQuery() {
        super();
        // TODO Auto-generated constructor stub
    }
	@Override
	protected void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession(false);
		if (session == null){
			error(request, response, "init error");
			return;
		}

		find(request, response, session);

	}
	

	private void find(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws ServletException, IOException {
		String query = (String)request.getParameter("query"); // 検索条件
		query = URLDecoder.decode(query, "UTF-8");
	
		EndpointSettings es = getEndpointSettings(request);
		if (es == null){
			error(request, response, "endpoint hasn't set");
			return;
		}
		System.out.println("ep:"+es.getEndpoint());

		SparqlAccessor sa = SparqlAccessorFactory.createSparqlAccessor(es);

		
		String json = find(sa, query);
		
		if (json != null){
			response(request, response, json);
			
		} else {
			error(request, response, "json error");
		}

		
	}

	private String find(SparqlAccessor sa, String query) throws ServletException, IOException {

		
		List<Map<String, String>> ret = new ArrayList<Map<String, String>>();
		try {
			SparqlResultSet rs = sa.find(query, null);

			List<Map<String, RDFNode>> results = rs.getDefaultResult();
			
			List<String> targetList = null;
			
			
			// 結果をまずはlistに追加
//			Map<String, String> prevData = new LinkedHashMap<String, String>();
			if (results != null){
				for (Map<String, RDFNode> result : results){
					if (targetList == null){
						targetList = new ArrayList<String>();
						for (String key : result.keySet()){
							targetList.add(key);
						}
					}
					
					Map<String, String> map = new LinkedHashMap<String, String>();

					for (String preds : targetList){
//						String prevRDF = prevData.get(preds);

						RDFNode valiable = result.get(preds);
//						if (prevRDF != null && valiable != null && getString(valiable).equals(prevRDF)){
//							map.put(preds, "<same>same</same>"); // TODO 前データと同じ
//						} else {
							map.put(preds, getString(valiable));
//						}
//						prevData.put(preds, getString(valiable));
					}
					ret.add(map);
				}
			}

			ResultPack rp = new ResultPack();
			rp.setResults(ret);
			rp.setHasNext(rs.isHasNext());
			rp.setHasPrev(false);

			
			String json = JSON.encode(rp);
			
			return json;
		} catch (Exception e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
		return null;

		
	}

}
