package com.tivoli.jmx.tutorial.server;

import java.io.FileInputStream;
import java.net.ProtocolException;
import java.io.InputStream;
import java.io.IOException;
import java.io.BufferedOutputStream;
import java.io.BufferedInputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Handler extends Thread {
  private Request request;
  private boolean active;
  private java.lang.Object activationLock;
  private HandlerPool homePool;

  public Handler(HandlerPool homePool) {
    this.activationLock = new Object();
    this.homePool = homePool;
    this.active = false;
  }

  public void activate(Request request) {
    synchronized (this.activationLock) {
      this.request = request;
      this.active = true;

      this.activationLock.notify();
    }
  }

  private void badRequestResponse() {
    try {
      OutputStream out = new BufferedOutputStream(request.getOutputStream());
      out.write(new String("HTTP 1.0 500 OK\r\nContent-type: text/html\r\n\r\n").getBytes());
      out.write(new String("<html><head><title>Protocol Error</title></head><body>BAD REQUEST</body></html").getBytes());
      out.flush();
      out.close();
    } catch (IOException x) {
      System.err.println(x);
    }
  }

  public void deactivate() {
    synchronized (activationLock) {
      this.request = null;
      this.active = false;
    }
    homePool.release(this);
  }

  private byte[] readRequestedFile(String file) throws java.io.IOException {
    StringBuffer fileBuffer = new StringBuffer();
    InputStream in = new BufferedInputStream(new FileInputStream(file));
    for (int c = in.read(); c != -1; c = in.read()) {
      fileBuffer.append((char) c);
    }
    in.close();
    return fileBuffer.toString().getBytes();
  }

  public void run() {
    while (true) {
      synchronized (activationLock) {
        while (active == false) {
          try {
            activationLock.wait();
          } catch (InterruptedException x) {}
        }
      }

      try {
        request.open();
        request.log();

        OutputStream out = new BufferedOutputStream(request.getOutputStream());
        byte[] fileBytes = readRequestedFile(request.getURI());
        out.write(new String("HTTP 1.0 200 OK\r\nContent-type: text/html\r\n\r\n").getBytes()); 
        out.write(fileBytes);
        out.flush();
        out.close();
      } catch (ProtocolException x) {
        badRequestResponse();
      } catch (IOException x) {
        System.err.println(x);
      } finally {
        request.close();
      }

      deactivate();
    }
  }
}