import java.io.*;
import java.util.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ConnectionAuthenticationServlet extends HttpServlet {

  private boolean isDBDriverLoaded = false;
  private String driverLoadingError = null;

  public void init() {
    /*
     * On charge le driver jdbc pour Oracle.
     */
    try {
      DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
      isDBDriverLoaded = true;
    } catch (SQLException x) {
      isDBDriverLoaded = false;
      driverLoadingError = x.toString();
    } 
  }

  public void destroy() {
    /*
     * On ne fait rien !
     */
  }

  public void service(HttpServletRequest request, HttpServletResponse response)
	throws IOException { 
    /*
     * On teste si la classe du driver jdbc Oracle a ete bien chargee
     */
    if (!isDBDriverLoaded) {
      serviceError(response, driverLoadingError);
      return;
    }
    /* 
     * On recupere les parametres envoyes a la servlet.
     */
    Enumeration clientParamEnum = request.getParameterNames();
    /* 
     * On verifie qu'il s'agisse bien de "PID" et "PASSWD" et uniquement ces deux
     * parametres. 
     */
    boolean isClientDataCorrect = false;
    if (clientParamEnum.hasMoreElements()) {
      String paramS = (String)clientParamEnum.nextElement();
      if (paramS.equals("PID") && clientParamEnum.hasMoreElements()) {
	paramS = (String)clientParamEnum.nextElement();
	if (paramS.equals("PASSWD")) {
	  isClientDataCorrect = true;
	}
      } else if (paramS.equals("PASSWD") && clientParamEnum.hasMoreElements()) {
	paramS = (String)clientParamEnum.nextElement();
	if (paramS.equals("PID")) {
	  isClientDataCorrect = true;
	}
      }
    }
    if (clientParamEnum.hasMoreElements())
      isClientDataCorrect = false;
    if (!isClientDataCorrect) {
      serviceError(response, "Les types de données envoyées sont incorrects");
      return;
    }
    /*
     * On recupere les valeurs des parametres.
     */
    String pidS = request.getParameter("PID");
    String passwd = request.getParameter("PASSWD");
    if (pidS.equals("") || passwd.equals("")) {
      serviceError(response, "Vous n'avez pas renseigné tous les champs");
      return;
    }
    int pid = -1;
    try {
      pid = Integer.parseInt(pidS);
    } catch (NumberFormatException x){
      serviceError(response, x.toString());
      return;
    }
    /*
     * On ouvre une connection en utilisant le driver thin.
     * Le compte Oracle utilise est :
     *  login : _mael
     *  password : mastere
     *  station : liszt
     *  port TCP : 1526
     *  sid : cour7a
     */
    Connection aConnection = null;
    try {
      aConnection = DriverManager.getConnection("jdbc:oracle:thin:@liszt:1526:cour7a","_mael","mastere");
    } catch (SQLException x) {
      serviceError(response, x.toString());
      return;
    }
    /*
     * On cree un statement SQL ...
     */
    Statement aStmt = null;
    try {
      aStmt = aConnection.createStatement();
    } catch (SQLException x) {
      serviceError(response, x.toString());
      try {
	aConnection.close();
      } catch (SQLException e) {}
      return;
    }  
    /*
     * ... Pour executer une requete :
     * On veut savoir si le mot de passe passwd pour le producteur numero pid
     * est correct.
     */
    ResultSet aRSet = null;
    try {
      aRSet  = aStmt.executeQuery("select p.prenomp, p.nomp, p.np, passwordp.np from p, passwordp where passwordp.np = " + pid + " and passwordp.pwd = '" + passwd + "' and p.np = passwordp.np");
    } catch (SQLException x) {
      serviceError(response, x.toString());
      try {
	aConnection.close();
      } catch (SQLException e) {}
      return;
    }
    /*
     * Si le resultat est no rows selected ...
     * On retourne au client un refus.
     * Sinon on a un seul t-uple ...
     */
    String prenom = null;
    String nom = null;
    try {
      if (aRSet.next()) {
	prenom = aRSet.getString(1); // on recupere la 1ere colonne : prenomp
	nom = aRSet.getString(2);    // on recupere la 2eme colonne : nomp
      } else {
	serviceError(response, "L'accès vous est refusé");
	try {
	  aConnection.close();
	} catch (SQLException x) {}
	return;
      }
    } catch (SQLException x) {
      serviceError(response, x.toString());
      try {
	aConnection.close();
      } catch (SQLException e) {}
      return;
    }
    /*
     * On cree une session HTTP. C'est un service offert par l'API Servlet
     * (HTTP est state-less : il n'y a pas de notion de session).
     * Dans notre cas, les sessions sont represente par des cookies
     * ("SESSIONID" valeur). Si on ne veut pas utiliser les cookies, les
     * sessions peuvent etre representees en utilisant l'encodage d'URL.
     * Cependant ce n'est pas une bonne solution puisque le client peut
     * changer le code de l'URL ...
     */
    HttpSession clientSession  = request.getSession(true);
    /*
     * On peut associer des objets a une session. Ainsi des donnees peuvent
     * etre partages entre plusieurs servlets d'une meme session.
     */
    clientSession.setAttribute("prod", new Integer(pid));
    if (prenom != null)
      clientSession.setAttribute("prenom", prenom);
    if (nom != null)
      clientSession.setAttribute("nom", nom);
    clientSession.setAttribute("connection", aConnection);
    /*
     * Tout s'est bien passe. On redirige donc le client vers une autre
     * servlet !
     */
    response.sendRedirect("http://zazie.enst.fr:8080/servlet/RequestServlet");
  }

  private void serviceError(HttpServletResponse response, String message)
	throws IOException {
    /*
     * On va renvoyer au client du texte HTML avec un peu de javascript.
     */
    response.setContentType("text/HTML");
    PrintWriter errorHTMLPage = response.getWriter();

    errorHTMLPage.println("<html>");
    errorHTMLPage.println("  <head>");
    errorHTMLPage.println("    <title>ConnAuthServlet</title>");
    errorHTMLPage.println("    <script language=\"JavaScript\">");
    errorHTMLPage.println("      function goBackToPage() {");
    errorHTMLPage.println("        window.location.href = \"http://zazie.enst.fr:8080/exo2.html\";");
    errorHTMLPage.println("      }");
    errorHTMLPage.println("      function startTimer() {");
    errorHTMLPage.println("        window.setTimeout(\"goBackToPage()\", 5000);");
    errorHTMLPage.println("      }");
    errorHTMLPage.println("    </script>");
    errorHTMLPage.println("  </head>");
    errorHTMLPage.println("  <body bgcolor=\"ivory\" onload=\"startTimer()\">");
    errorHTMLPage.println("    <center>");
    errorHTMLPage.println("      <h1>" + message + "</h1>");
    errorHTMLPage.println("      <h3>Vous allez être redirigé vers la page précédente dans quelques secondes ...</h3>");
    errorHTMLPage.println("    </center>");
    errorHTMLPage.println("  </body>");
    errorHTMLPage.println("</html>");
	}
}