/*
 * Copyright (c) 2009, syuu
 * Licensed under the NicoCache License.
 */

package com.dokukino.genkidama;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.positrium.waket.URLMap;
import org.positrium.waket.XMLConfigLoader;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

//import dareka.Main;
import dareka.common.CloseUtil;
import dareka.common.Config;
import dareka.processor.HttpHeader;
import dareka.processor.HttpUtil;
import dareka.processor.impl.Cache;

public class DataServer {
	public static Log logger = LogFactory.getLog(DataServer.class);
	
	XMLConfigLoader loader = new XMLConfigLoader(new File("DataServer.xml"));
	
	public void bind(int port) throws IOException {
        HttpHandler nicoCacheHandler = new HttpHandler() {
			public void handle(HttpExchange he) throws IOException {
                String cacheid = he.getRequestURI().getPath().replaceFirst("^/nc/", "");
                Cache cache = new Cache(cacheid, null);
                logger.info("cache requested: " + cacheid);
                if(cache.exists() && !GenkidamaManager.checkDeleted(cache.getId())) {
                	logger.info("publishing cache: " + cache.getCacheFileName());
                	he.getResponseHeaders().set(HttpHeader.CONTENT_TYPE, "video/flv");
                	he.sendResponseHeaders(HttpURLConnection.HTTP_OK, cache.length());
                	OutputStream out = he.getResponseBody();
                	InputStream in = cache.getInputStream();
                	try {
                		HttpUtil.sendBody(out, in, cache.length());
                	} finally {
                		CloseUtil.close(out);
                		CloseUtil.close(in);
                	}
                }else{
                	he.sendResponseHeaders(HttpURLConnection.HTTP_NOT_FOUND, 0);
                	he.getRequestBody().close();
                }
            }
        };
        
        HttpHandler proxyPacHandler = new HttpHandler() {
			public void handle(HttpExchange he) throws IOException {
				File file = new File(Config.getString("dhtProxyPac", "proxy.pac"));
            	he.sendResponseHeaders(HttpURLConnection.HTTP_OK, file.length());
            	he.getResponseHeaders().set(HttpHeader.CONTENT_TYPE, "text/plain");
            	if(file.exists()) {
            		OutputStream out = he.getResponseBody();
                	InputStream in = new FileInputStream(file);
	            	try {
	            		HttpUtil.sendBody(out, in, file.length());
	            	} finally {
	            		CloseUtil.close(out);
	            		CloseUtil.close(in);
	            	}
            	}else{
                	he.sendResponseHeaders(HttpURLConnection.HTTP_NOT_FOUND, 0);
                	he.getRequestBody().close();
                }
			}
        };
        
        List<URLMap> list = loader.getMap().getURLMap();
        
        HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
        server.createContext("/nc/", nicoCacheHandler);
        server.createContext("/proxy.pac", proxyPacHandler);
        
        for (URLMap bean : list) {
        	HttpHandler handleObject = null;
        	try {
        		handleObject = (HttpHandler) Class.forName(bean.getClassname()).newInstance();
			} catch (InstantiationException e) {
				logger.error("Error Occurs:",e);
			} catch (IllegalAccessException e) {
				logger.error("Error Occurs:",e);
			} catch (ClassNotFoundException e) {
				logger.error("Error Occurs:",e);
			}
			
			server.createContext(bean.getUrl(), handleObject);
        }
        server.start();
	}
}
