package page.distribute;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.wikiwebserver.core.WareHouse;
import org.wikiwebserver.distribute.interfaces.Task;
import org.wikiwebserver.distribute.interfaces.WorkerNode;
import org.wikiwebserver.distribute.se.worker.task.ImagePreviewTask;
import org.wikiwebserver.distribute.server.TaskStub;
import org.wikiwebserver.handler.http.HTTPException;
import org.wikiwebserver.handler.http.HTTPHandler;
import org.wikiwebserver.handler.http.HTTPHeaders;
import org.wikiwebserver.handler.http.interfaces.CacheableHTTPResponse;
import org.wikiwebserver.handler.http.interfaces.HTTPResponder;

import page.tools.entity.Browser;

import static page.distribute.FileBrowser.decodePath;

public class ImagePreview implements HTTPResponder, CacheableHTTPResponse {
	
	private static final long DEFAULT_EXPIRE = 48 * 60 * 60 * 1000;

	private final WorkerNode node;
	private final String path;
	private final int offset;
	
	public ImagePreview(WorkerNode node, String path, int offset) {
		this.node = node;
		this.path = path;
		this.offset = offset;
	}
	
	
    public Object respond(HTTPHandler conn) throws HTTPException {
        
    	String decodedPath = decodePath(path);
    	
    	Task task = new ImagePreviewTask();
        task.setTaskInputMeta(offset + "|" + decodedPath);     	
		
        Browser browser = Browser.getBrowser(conn);
        if (browser != null) {
			String password = (String) browser.get("nodeTaskPassword");
		    task.setTaskPassword(password);
        }	
		
		InputStream fileData = null;
    	try {
    		TaskStub stub = node.addNewTaskAndWait(task);
			
    		HTTPHeaders responseHeaders = conn.getResponse().getHeaders();
			
    		Object output = stub.getOutput();
    		
            String contentLength = stub.getTaskOutputMeta(); 
    		responseHeaders.set("Content-Length", contentLength);
    		
            if (output instanceof byte[]) {
                conn.getOutputStream().write((byte[]) output);
            }    		

    		if (output instanceof InputStream) {
				fileData = (InputStream) output;
				OutputStream out = conn.getOutputStream();			
				WareHouse.proxyStream(fileData, out);
    		}
			
			return null;
			
		} 
    	catch (Exception ex) {
			String msg = "Failed to complete transfer";
			throw new HTTPException(500, msg, ex);
		}
		finally {
			// This will end the transfer from the connected node
			try { fileData.close(); } catch (Exception ex2) {}			
		}
    }

    public String getCacheKey() {
    	return node.getNodeId() + path + offset + node.getConfigurationId();
    }
    
    public long getExpireTime() {
        return System.currentTimeMillis() + DEFAULT_EXPIRE;
    }

	public void init(HTTPHandler conn) throws IOException {
        conn.getResponse().getHeaders().set("Content-Type", "image/jpeg");      
	}
}
