/*
 * 
 * Copyright
 *  2009 axYus - www.axyus.com
 *  2009 Christophe Marchand <christophe.marchand@axyus.com>
 * 
 * This file is part of XEMELIOS.
 * 
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * XEMELIOS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 */
package fr.gouv.finances.dgfip.xemelios.batch;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;

/**
 *
 * @author Christophe Marchand <christophe.marchand@axyus.com>
 */
public class BatchInformationListener {

    private boolean stop = false;
    private BatchRunner runner;
    private ServerSocket server_socket = null;
    private static BatchInformationListener instance = null;

    public BatchInformationListener(BatchRunner runner, int port) {
        super();
        BatchInformationListener.instance=this;
        this.runner = runner;

        try {
            server_socket = new ServerSocket(port);
            while (!stop) {
                Socket socket = server_socket.accept();

// Construct handler to process the HTTP request message.
                try {
                    httpRequestHandler request = new httpRequestHandler(socket, runner);
                    Thread thread = new Thread(request);

                    // Start the thread.
                    thread.start();
                } catch (Exception e) {
                }
            }
        } catch (IOException e) {
        } finally {
            try {
                server_socket.close();
            } catch (Throwable t) {
            }
        }
    }

    public void stop() {
        stop = true;
        try {
            server_socket.close();
        } catch (IOException ioEx) {
            // on ignore
        }

    }
    public static BatchInformationListener getInstance() { return instance; }
}

class httpRequestHandler implements Runnable {

    final static String CRLF = "\r\n";
    Socket socket;
    OutputStream output;
    BufferedReader br;
    private BatchRunner runner;

    // Constructor
    public httpRequestHandler(Socket socket, BatchRunner runner) throws Exception {
        this.socket = socket;
        this.runner = runner;
        this.output = socket.getOutputStream();
        this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    }

    // Implement the run() method of the Runnable interface.
    public void run() {
        try {
            processRequest();
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    private void processRequest() throws Exception {
        while (true) {

            String headerLine = br.readLine();
            if (headerLine.equals(CRLF) || headerLine.equals("")) {
                break;
            }

            StringTokenizer s = new StringTokenizer(headerLine);
            String temp = s.nextToken();

            if (temp.equals("GET")) {
                String serverLine = "Xemelios batch information serveur";
                String statusLine = null;
                String contentTypeLine = null;
                String entityBody = null;
                String contentLengthLine = "error";
                String informations = null;
                if (runner != null) {
                    statusLine = "HTTP/1.0 200 OK" + CRLF;
                    contentTypeLine = "Content-type: text/plain" + CRLF;
                    informations = runner.getInformations();
                    contentLengthLine = "Content-Length: " + Integer.toString(informations.length()) + CRLF;
                } else {
                    statusLine = "HTTP/1.0 404 Not Found" + CRLF;
                    contentTypeLine = "text/html";
                    entityBody = "<HTML>" +
                            "<HEAD><TITLE>404 Not Found</TITLE></HEAD>" +
                            "<BODY>404 Not Found" + "<br>usage: http://server:" + socket.getPort() + "/fileName.html</BODY></HTML>";
                }

                output.write(statusLine.getBytes());
                output.write(serverLine.getBytes());
                // Send the content type line.
                output.write(contentTypeLine.getBytes());
                // Send the Content-Length
                output.write(contentLengthLine.getBytes());
                // Send a blank line to indicate the end of the header lines.
                output.write(CRLF.getBytes());

                // Send the entity body.
                if (runner != null) {
                    output.write(informations.getBytes());
                } else {
                    output.write(entityBody.getBytes());
                }
            }
        }

        try {
            output.close();
            br.close();
            socket.close();
        } catch (Exception e) {
        }
    }

    private static String contentType(String fileName) {
        if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
            return "text/html";
        } else if (fileName.endsWith(".zip")) {
            return "multipart/x-zip";
        }

        return "";
    }
}
