/*
 * Scone - The Web Enhancement Framework
 * Copyright (C) 2009 Harald Weinreich, Volkert Buchmann, Frank Wollenweber, Torsten Haß
 *
 * This program 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.
 * 
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package scone.accesstracking;


import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
import java.util.Vector;

import scone.netobjects.Person;
import scone.netobjects.PersonCache;
import scone.netobjects.SimpleUri;
import scone.netobjects.User;
import scone.netobjects.UserCache;

import com.ibm.wbi.RequestEvent;
import com.ibm.wbi.RequestRejectedException;
import com.ibm.wbi.protocol.http.DocumentInfo;
import com.ibm.wbi.protocol.http.HttpGenerator;
import com.ibm.wbi.protocol.http.HttpRequest;
import com.ibm.wbi.protocol.http.HttpResponse;
import com.ibm.wbi.protocol.http.beans.FileGenerator;
import com.ibm.wbi.protocol.http.beans.FormHelper;
import com.ibm.wbi.protocol.http.beans.StaticHtmlGenerator;


/**
 * This meg creates the user logging entries in the access database.<P>
 * If the user is unknown (no cookie ID to the host tracking.scone.de is set)
 * a login screen is displayed<P>
 * After the login, a cookie is set and from now on the userId from this cookie is used.<P>\n
 * The meg is called when
 * <OL>
 * <LI> a transfer is startet (filename = _start)
 * <LI> the page was loaded (filename = _load)
 * <LI> the page was left (filename = _stop)
 * </OL>\n
 * The correcconding JavaScript-Code is inserted by the JavaScriptAdder.<BR>
 * The JS-methods stop() and loaded() calls are inserted by the BodyEventAdder.<BR>
 * The onClick-events to all the Links can be added by the LinkEventAdder.
 */
public class UserHandlingMeg extends HttpGenerator {

    private DocumentInfo documentInfo;  
    private String        file;
    private Properties   formParameter;
    private HttpRequest  request;
    private HttpResponse response;
    private String       id;
    private long         userId = 0L;

    public void handleRequest(RequestEvent e) throws RequestRejectedException {

        documentInfo = (DocumentInfo) e.getRequestInfo(); // get RequestInfo
        file = documentInfo.getPath();           // get Path+File of the URL
        formParameter = FormHelper.interpretFormData(e);  // get Query Parameter from URL
        request = new HttpRequest(e, true);          // Get the request header
        id = request.getCookie("ID");          // Get Cookie "ID"
        try {
            if (id != null) {
                userId = Long.parseLong(id);
            }
        } catch (NumberFormatException ex) {
            System.err.println("Error: Cookie ID is no number");
            userId = 0L;
            id = null;
        }

        HttpGenerator g = null;

        if (file.equals("/_register"))  // post from user login-screen
        {  
            StaticHtmlGenerator sg = new StaticHtmlGenerator(); // Return generated document to the client

            if (request.getMethod().equals("POST"))             // The Data was send by POST method
            {
                String content = request.getContent();
                // String uId    = String.valueOf(Math.abs(new Random(new Date().getTime()).nextLong()));  // Create a positive long random number as String.

                String user = formParameter.getProperty("user");

                if (user == null) {
                    user = "";
                }
                String password = formParameter.getProperty("password");

                if (password == null) {
                    password = "";
                }
                String firstName = formParameter.getProperty("firstName");

                if (firstName == null) {
                    firstName = "";
                }
                String secondName = formParameter.getProperty("secondName");

                if (secondName == null) {
                    secondName = "";
                }
                String lastName = formParameter.getProperty("lastName");

                if (lastName == null) {
                    lastName = "";
                }
                String organization = formParameter.getProperty("organization");

                if (organization == null) {
                    organization = "";
                }
                String email = formParameter.getProperty("email");

                if (email == null) {
                    email = "";
                }
                String referrer = formParameter.getProperty("referrer");

                if (user.length() > 0 && password.length() > 0)  // uId.length()>0 && 
                {
                    User u = UserCache.get(user);

                    id = u.getUserId();

                    System.out.println(id);
                    System.out.println(u.getUserName());
               
                    u.setUserPass(password);
                    String personId = SimpleUri.getHexHashCode(id + firstName + secondName + lastName + organization + email);

                    u.setPersonId(personId);  // One person can have several User IDs.
                    u.store();

                    Person p = PersonCache.getById(personId);  // Get a new Person object...

                    p.setFirstName(firstName);
                    p.setSecondName(secondName);
                    p.setLastName(lastName);
                    p.setOrganization(organization);
                    p.setEmail(email);
                    p.store();

                    String reply = ("<body bgcolor='#ffffff'><H1>Welcome "
                            + firstName + " " + lastName + "</H1>\n"
                            + "You are registered as user <B>" + user
                            + "</B> with userId: <B>" + id + "</B>"
                            + "<P><I>Scone</I> is ready to support you now.<p>Please restart the Internet Explorer!<p>\n");

                    if (referrer != null) {
                        reply += "continue: <a href='" + referrer + "'>"
                                + referrer + "</a><p>";
                    }
                    sg.setStaticHtml(reply);
                    // "<P>If your browser returns to this registration procedure unexpectedly, please restart your browser.");     
                } else {
                    sg.setStaticHtml("<body bgcolor='#ffffff'><H1>Please enter a user name and a password!</H1>" + "<A HREF=\"http://users.scone.de/registration.html\">Return to registration screen.</A>");    // Set dummy text
                }
       
            } else {
                sg.setStaticHtml("<body bgcolor='#ffffff'><H1>Error! Wrong FORM method! POST needed.</H1>");    // Set dummy text
            }
            g = sg;                                                    // Return Generator
      
        } else if (file.equals("/_login"))  // Login if user known in database...
        {  
            StaticHtmlGenerator sg = new StaticHtmlGenerator(); // Return generated document to the client

            if (request.getMethod().equals("POST"))             // The Data was send by POST method
            {
                String content = request.getContent();
                String user = formParameter.getProperty("user");

                if (user == null) {
                    user = "";
                }
                String password = formParameter.getProperty("password");

                if (password == null) {
                    password = "";
                }
                if (user.length() > 0 && password.length() > 0) {
                    User u = UserCache.check(user, password);

                    if (u != null)  // user with this password
                    {
                        id = u.getUserId();
                        Person p = PersonCache.getById(id);  // Get a new Person object...

                        sg.setStaticHtml("<body bgcolor='#ffffff'><H1>Welcome " + p.getFirstName() + " " + p.getLastName() + "</H1>\n" + "You are logged in as user <B>" + user + "</B> with userId: <B>" + id + "</B>" + ".");
                        // "<P>If your browser returns to this registration procedure unexpectedly, please restart your browser.");     
                    } else {
                        sg.setStaticHtml("<body bgcolor='#ffffff'><H1>Login Failed</H1>\n" + "Username or password wrong. Please try again.<P>" + "<A HREF=\"http://users.scone.de/login.html\">Return to login screen.</A><BR>\n" + "<A HREF=\"http://users.scone.de/registration.html\">Register new user.</A><BR>");    
                        // "<P>If your browser returns to this registration procedure unexpectedly, please restart your browser.");     
                    }
                } else {
                    sg.setStaticHtml("<body bgcolor='#ffffff'><H1>Login Failed</H1>" + "Please enter user name <B>and</B> password to login!<P>" + "<A HREF=\"http://users.scone.de/login.html\">Return to login screen.</A><BR>\n" + "<A HREF=\"http://users.scone.de/registration.html\">Register new user.</A><BR>");    
                }
       
            } else {
                sg.setStaticHtml("<body bgcolor='#ffffff'><H1>Error! Wrong FORM method! POST needed.</H1>");    // Set dummy text
            }
            g = sg;                                                    // Return Generator
        } else if (file.equals("/_list"))  // list all users in Database...
        {  
            StaticHtmlGenerator sg = new StaticHtmlGenerator(); // Return generated document to the client
            String htmlCode;

            htmlCode = "<HTML>\n<HEAD>\n<TITLE>Alle Scone users</TITLE>\n</HEAD>\n<BODY bgcolor='#ffffff'>\n";
            htmlCode += "<H1>All users registered by <I>Scone</I></H1>";
            htmlCode += "<TABLE bgcolor=\"#90D0D0\" CELLSPACING=2 CELLPADDING=5><TR><TH bgcolor=\"#F0FFFF\">User ID</TH><TH bgcolor=\"#F0FFFF\">User Name</TH><TH bgcolor=\"#F0FFFF\">Full Name</TH><TH bgcolor=\"#F0FFFF\">Organization</TH></TR>";
            System.out.println("1");
            Vector users = UserCache.getUsers("order by userName");

            // Create Table with all users
            System.out.println("2");
            for (int i = 0; i < users.size(); i++) {
                User u = (User) users.get(i);
                Person p = PersonCache.getById(u.getPersonId());

                htmlCode += "<TR><TD bgcolor=\"#E0FFFF\">" + u.getUserId()
                        + "</TD><TD bgcolor=\"#E0FFFF\">" + u.getUserName()
                        + "</TD><TD bgcolor=\"#E0FFFF\"><A HREF=\"mailto:"
                        + p.getEmail() + "\">" + p.getFirstName() + " "
                        + p.getSecondName() + " " + p.getLastName()
                        + "</A></TD><TD bgcolor=\"#E0FFFF\">"
                        + p.getOrganization() + "</TD></TR>";
            }
            htmlCode += "</TABLE></BODY></HTML>";
            sg.setStaticHtml(htmlCode);    
            g = sg;                                                    // Return Generator
        } else if (file.length() > 1) {
            // Create response from file
            // System.out.println("Returning: "+file);
            String ext = file.substring(file.lastIndexOf(".") + 1);
            // System.out.println(getContentType(ext));
            FileGenerator rg = new FileGenerator("resources/scone/proxy" + file, getContentType(ext));

            g = rg;
        } else {
            StaticHtmlGenerator sg = new StaticHtmlGenerator(); // Return generated document to the client
            String htmlCode;

            htmlCode = "<HTML>\n<HEAD>\n<TITLE>Scone user handling</TITLE>\n</HEAD>\n<BODY bgcolor='#ffffff'>\n";
            htmlCode += "<img src=\"http://users.scone.de/scone.jpg\"><BR>\n";
            htmlCode += "<H2><I>Scone</I> user handling options:</H2>\n";
            htmlCode += "<UL>\n";
            htmlCode += "<LI><A HREF=\"http://users.scone.de/login.html\">Login user</A><BR>\n";
            htmlCode += "<LI><A HREF=\"http://users.scone.de/registration.html\">Register new user</A><BR>\n";
            htmlCode += "<LI><A HREF=\"http://users.scone.de/_list\">List all users</A><BR>\n";
            htmlCode += "</UL>\n</BODY></HTML>";
            sg.setStaticHtml(htmlCode);    
            g = sg;                                                    // Return Generator
        }

        // Create response from file

        response = g.getHttpResponse();                   // Get http response header
        response.setCache(false);
        if (id != null)                                                  // Return Cookie to browser
        {
            // System.out.println((new Date()).getTime());
            long expiry = (new Date()).getTime()
                    + (1000l * 60l * 60l * 24l * 365l * 10l);  // 10 years expiry.
            // System.out.println(expiry);       
            Date expiryDate = new Date(expiry);                            // Create date object

            // WBIs addCookie doesn't work well...
            this.addCookie("ID", id, expiryDate, ".scone.de", "/", false);       // set cookie in Response: For Netscape
            this.addCookie("ID", id, expiryDate, "scone.de", "/", false);        // set cookie in Response: For IE 6 etc.
            this.addCookie("ID", id, expiryDate, "", "/", false);        // set cookie in Response: For IE 5.5
            // Domain Namen können ab IE 5.5 nur angegeben werden, wenn "scone.de" als trusted Site eingetragen ist...
            // this.addCookie("ID",id,expiryDate,"","/",false);        // set cookie in Response, WBIs addCookie is fucked....
        }
      
        // Send Response to Browser
        try {
            forwardRequest(g, e); 
        } catch (java.io.IOException ex) {
            System.out.println("Error sending response in UserHandlingMeg!");
        }

    }

    /*
     * Create most important mime types from file extensions
     */
    private String getContentType(String ext) {
        ext = ext.toLowerCase();
        if (ext.equals("txt")) {
            return "text/txt";
        }
        if (ext.equals("css")) {
            return "text/css";
        }
        if (ext.equals("js")) {
            return "application/x-javascript";
        }
        if (ext.equals("gif")) {
            return "image/gif";
        }
        if (ext.equals("jpg")) {
            return "image/jpeg";
        }
        return "text/html";
    }

    // WBI's addCookie is buggy...
    public void addCookie(String s, String s1, Date date, String s2, String s3, boolean flag) {
        StringBuffer stringbuffer = new StringBuffer(URLEncoder.encode(s) + "=" + URLEncoder.encode(s1));

        if (s2 != null && s2.length() != 0) {
            stringbuffer.append("; domain=" + s2);
        }
        if (s3 != null && s3.length() != 0) {
            stringbuffer.append("; path=" + s3);
        }
        if (date != null) {   // Das richtige Datumsformat für den IE anbieten!
            // SimpleDateFormat formatter = new SimpleDateFormat ("EEE, dd-MMM-yyyy HH:mm:ss z"); // 09-Nov-2030 23:59:00 GMT;
            SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss", Locale.US); // 09-Nov-2030 23:59:00 GMT;
            String dateString = formatter.format(date);

            stringbuffer.append("; expires=" + dateString + " GMT"); 
        }
        if (flag) {
            stringbuffer.append("; secure");
        }
        // stringbuffer.append(";");
        response.add("Set-Cookie", stringbuffer.toString());
    }

}

