package org.wikiwebserver.handler.http.responder;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import org.wikiwebserver.core.SecurityMan;
import org.wikiwebserver.core.WareHouse;
import org.wikiwebserver.core.WikiMap;
import org.wikiwebserver.handler.http.HTTPException;
import org.wikiwebserver.handler.http.HTTPHandler;
import org.wikiwebserver.handler.http.HTTPPostReader;
import org.wikiwebserver.handler.http.interfaces.HTTPResponder;

public class WikiMapSyncResponder implements HTTPResponder {

	public Object respond(HTTPHandler conn) throws IOException {
		
	    String password = conn.getRequest().getHeaders().getFirst("X-Server-Password");
		SecurityMan.checkSuperPassword(password); // throws exception if fails
		
		HTTPPostReader postedData = (HTTPPostReader) conn.getRequest().getData();
		ByteArrayInputStream in = new ByteArrayInputStream(postedData.readFully());		
	    
	    try {
			System.out.println("Receiving sync data (" + WareHouse.formatSize(in.available()) + ")");	   
		    ObjectInputStream ois = new ObjectInputStream(new GZIPInputStream(in));			
			readMapData(ois);
			ois.close();
		} 
	    catch (ClassNotFoundException ex) {
			throw new HTTPException(500, "Unsupported object in map", ex);
		}

		return "Accepted";
	}
	
	@SuppressWarnings("unchecked")
	public void readMapData(ObjectInputStream ois) throws IOException, ClassNotFoundException {

		boolean moreMaps = ois.readBoolean();

		while (moreMaps) {
			
			String[] heirarchy = (String[]) ois.readObject();
		    String accessorClassName = (String) ois.readObject();
		    int maxSize = ois.readInt();

		    @SuppressWarnings("rawtypes")
			Map<String, Object> plainValues = (Map) ois.readObject();

		    WikiMap map = WareHouse.getWikiMap(heirarchy);
		    if (map == null) {
		    	map = WareHouse.initWikiMap(maxSize, accessorClassName, heirarchy);
		    }
		    
		    System.out.println("Recieving " + map.getPath() + " (" + plainValues.size() + ")");

		    map.putAll(plainValues);

		    moreMaps = ois.readBoolean();
		}
	}	
}

