package edu.isi.karma.mapreduce.driver;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Iterator;

import org.apache.hadoop.io.Text;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.isi.karma.kr2rml.ContextIdentifier;
import edu.isi.karma.kr2rml.writer.JSONKR2RMLRDFWriter;
import edu.isi.karma.kr2rml.writer.KR2RMLRDFWriter;

public class JSONMapper extends BaseRDFMapper {
	private Text reusableOutputValue = new Text("");
	private Text reusableOutputKey = new Text("");
	private String atId = "@id";
	
	private static Logger LOG = LoggerFactory.getLogger(JSONMapper.class);
	
	@Override
	protected KR2RMLRDFWriter configureRDFWriter(StringWriter sw) {
		PrintWriter pw = new PrintWriter(sw);
		KR2RMLRDFWriter outWriter = new JSONKR2RMLRDFWriter(pw, karma.getBaseURI());
		ContextIdentifier contextId = karma.getContextId();
		try {
			atId = getAtId(karma.getGenerator().loadContext(contextId).getJSONObject(("@context")));
		} catch(Exception e)
		{}
		return outWriter;
	}

	@Override
	protected void writeRDFToContext(Context context, String results)
			throws IOException, InterruptedException {
	
			JSONArray generatedObjects = new JSONArray(results);
			for(int i = 0; i < generatedObjects.length(); i++)
			{
				try{
					if (generatedObjects.getJSONObject(i).has(atId)) {
						reusableOutputKey.set(generatedObjects.getJSONObject(i).getString(atId));
					}
					else {
						reusableOutputKey.set(generatedObjects.getJSONObject(i).toString());
					}
					reusableOutputValue.set(generatedObjects.getJSONObject(i).toString());
					context.write(reusableOutputKey, new Text(reusableOutputValue));
				}catch(ArrayIndexOutOfBoundsException ae){
					LOG.error("************ARRAYEXCEPTION*********:" + ae.getMessage() + "SOURCE: " + generatedObjects.getJSONObject(i).toString());
				}
			}
		
	}

	private String getAtId(JSONObject c) {
		@SuppressWarnings("rawtypes")
		Iterator itr = c.keys();
		while (itr.hasNext()) {
			String key = itr.next().toString();
			try {
				if (c.get(key).toString().equals("@id")) {
					return key;
				}
			}
			catch(Exception e) 
			{

			}
		}
		return atId;
	}
}

@@ -1913,24 +1913,189 @@
 oString());%0A
+%09%09%09%09%09throw new ArrayIndexOutOfBoundsException(%22************ARRAYEXCEPTION*********:%22 + ae.getMessage() + %22SOURCE: %22 + generatedObjects.getJSONObject(i).toString());%0A
 %09%09%09%09%7D%0A%09%09%09%7D%0A%09

throw new exception arrayindexoutofexception