/* $Id: Configure.java,v 1.7 2003/07/29 22:00:00 ryanlee Exp $
 */

import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.hp.hpl.mesa.rdf.jena.common.*;
import com.hp.hpl.mesa.rdf.jena.mem.ModelMem;
import com.hp.hpl.mesa.rdf.jena.model.*;
import com.hp.hpl.mesa.rdf.jena.vocabulary.RDF;
import com.hp.hpl.mesa.rdf.jena.vocabulary.RSS;

import vocabulary.DC;
import vocabulary.GLANCE;

import util.Base64Decoder;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;


public class Configure extends HttpServlet {
    ResourceBundle rb = ResourceBundle.getBundle("LocalStrings");
    PrintWriter out = null;

    Hashtable users = new Hashtable();
    String auth = null;
    HttpSession session = null;

    public void init(ServletConfig config)
	throws ServletException {
	super.init(config);
    }

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) 
	throws IOException, ServletException  {

	// get the users session
	session = request.getSession();
	session.setMaxInactiveInterval(-1);	
	// get the model stored in the session
	Model glance = (Model) session.getAttribute("model");
	Model personal = (Model) session.getAttribute("personal");

	// get authentication information
	auth = request.getHeader("Authorization");

	// if no auth, then challenge for authorization
	if (auth == null) {
	    response.sendError(response.SC_UNAUTHORIZED);
	    return;
	}

	// don't cache the output
	response.setHeader("Cache-Control", "no-cache");

	String userpassEncoded = auth.substring(6);
	String userpassDecoded = Base64Decoder.decode(userpassEncoded);
	String user = null;
	user = GlanceAuth.getUsername(userpassDecoded);
	String prefuri = rb.getString("glance.prefuri");

	// if no user in URI, then redirect
	if (request.getParameter("user") == null) {
	    Enumeration params = request.getParameterNames();
	    String finaluri = prefuri + "?user=" + user;
	    String pName;
	    String [] pValue;
	    while(params.hasMoreElements()) {
		pName  = (String) params.nextElement();
		pValue = request.getParameterValues(pName);
		for (int j = 0; j < pValue.length; j++) {
		    finaluri += "&" + pName + "=" + URLEncoder.encode(pValue[j]);
		}
	    }
	    response.sendRedirect(finaluri);
	    return;
	}

	// get output
        out = response.getWriter();

	// if no model exisits, create one
	if (glance == null) {
	    glance = new ModelMem();
	    
	    // configure base model
	    String configuri = rb.getString("glance.configuri");

	    try {
		Glance.readFeed(glance, configuri, auth);
	    } catch (Exception e) {
		System.out.println(e);
	    }

	    // save model
	    session.setAttribute("model", glance);
	}

	if (personal == null) {
	    personal = new ModelMem();
	    session.setAttribute("personal", personal);
	}

	String personaluri = rb.getString("glance.personaluri");

	try {
	    Glance.readFeed(personal, personaluri, auth);
	} catch (Exception e) {
	    System.out.println(e);
	}

	String configmemberuri = rb.getString("glance.configmemberuri");
	    
	try {
	    Glance.readFeed(glance, configmemberuri, auth);
	} catch (Exception e) {
	    System.out.println(e);
	}

	String configteamuri = rb.getString("glance.configteamuri");
	
	try {
	    Glance.readFeed(glance, configteamuri, auth);
	} catch (Exception e) {
	    System.out.println(e);
	}
	session.setAttribute("model", glance);

	String addfeed = request.getParameter("add");
	String rmfeed = request.getParameter("rm");
	String ptop = rb.getString("glance.personalfeed");
	String top = rb.getString("glance.feed");
	if (addfeed != null) {
	    try {
		addFeed(glance, personal, addfeed);
	    } catch (Exception e) {
		System.out.println(e);
	    }
	}

	if (rmfeed != null) {
	    try {
		removeFeed(personal, rmfeed);
	    } catch (Exception e) {
		System.out.println(e);
	    }
	}

	try {
	    response.setContentType("text/html");

	    String loginuri = rb.getString("glance.loginuri");
	    String abouturi = rb.getString("glance.abouturi");
	    String reseturi = rb.getString("glance.reseturi");
	    String exporturi = rb.getString("glance.exporturi");

	    String navigation = "<a href=\"" + Glance.makeUserURI(loginuri, user) + "\">Home</a> | ";
	    navigation += "<a href=\"" + abouturi + "\">About</a> | ";
	    navigation += "<a href=\"" + Glance.makeUserURI(prefuri, user) + "\">Preferences</a> | ";
	    navigation += "<a href=\"" + Glance.makeUserURI(exporturi, user) + "\">Export Preferences</a> | ";
	    navigation += "<a href=\"" + Glance.makeUserURI(reseturi, user) + "\">Reset Preferences</a>";
	    
	    Glance.printHeader(out, navigation, 0);

	    // check for feed in question (could be via http param else
	    // init param)
	    String feed = request.getParameter("feed");

	    if (feed == null) {
		// no parameter input, perhaps init... load inital value
		// from config file
		feed = top;
	    }
	    
	    Glance.readFeed(glance, feed, auth);
	    if (addfeed == null) {
		Glance.readFeed(personal, personaluri, auth);
	    }

	    // print personal outline
	    out.println("<div id=\"content\">");

	    out.println("<div class=\"formContainer\">");
	    out.println("<form action=\"import\" method=\"post\" enctype=\"multipart/form-data\">");
	    out.println("<p class=\"center\">Import Personal Feed: <input type=\"file\" name=\"feedfile\" /> <input type=\"submit\" value=\"Upload\" /></p>");
	    out.println("</form>");

	    out.println("<form action=\"webImport\" method=\"get\">");
	    out.println("<p class=\"center\">Import Web Feed: <input type=\"text\" name=\"config\" size=\"25\" value=\"http://\" /> <input type=\"submit\" value=\"Import\" /></p>");
	    out.println("</form>");
	    out.println("</div>");

	    out.println("<div class=\"conftoc\">");
	    out.println("<h3>Personal</h3>");
	    out.println("<p>Click to remove (first level only)</p>");
	    // print outline based on base feed
	    GlanceAuth.printOutline(personal, glance, personal.getResource(ptop), ptop, "rm", auth, out);
	    out.println("</div>");

	    // print glance outline
	    out.println("<div class=\"conftoc\">");
	    out.println("<h3>Available</h3>");
	    out.println("<p>Click to add</p>");
	    Resource base = glance.getResource(top);
	    Glance.printOutline(glance, base, top, "add", auth, out);
	    out.println("</div>");
	    out.println("</div>");
	    	
	    Glance.printFooter(out);
	} catch (Exception e) {
	    System.out.println(e);
	}
	out.close();
    }

    public void doPost(HttpServletRequest request,
		       HttpServletResponse response)
	throws IOException, ServletException {
        doGet(request, response);
    }
    
    public void addFeed(Model glanceModel,
			Model personalModel,
			String feed) throws RDFException {
	String personaluri = rb.getString("glance.personaluri");
	String ptop = rb.getString("glance.personalfeed");

	if (glanceModel == null || personalModel == null || feed == null) return;
	// check if this feed is in the list of personal, customized feeds
	try {
	    // items sequence
	    Seq s = personalModel.getResource(ptop).getProperty(RSS.items).getSeq();
	    Resource item = personalModel.getResource(feed);
	    // check if sequence already has this item
	    if (!s.contains(item)) {
		// if not, create it and add it
		Resource p = personalModel.createResource(feed);
		p.addProperty(GLANCE.displayTitle, glanceModel.getResource(feed).getProperty(GLANCE.displayTitle).getString());
		if(glanceModel.getResource(feed).hasProperty(GLANCE.access)) {
		    p.addProperty(GLANCE.access, glanceModel.getResource(feed).getProperty(GLANCE.access).getResource());
		}
		int ssize = personalModel.getResource(ptop).getProperty(RSS.items).getSeq().size();
		personalModel.getResource(ptop).getProperty(RSS.items).getSeq().add(ssize+1, p);
		// save the new model in this session
		session.setAttribute("personal", personalModel);
	    }
	} catch (Exception e) {
	    System.out.println(e);
	}
    }

    public void removeFeed(Model personal,
			   String feed) throws RDFException {
	String personaluri = rb.getString("glance.personaluri");
	String ptop = rb.getString("glance.personalfeed");

	if (personal == null || feed == null) return;

	// check if this feed is in the list of personal, customized feeds
	try {
	    Seq s = personal.getResource(ptop).getProperty(RSS.items).getSeq();
	    Resource item = personal.getResource(feed);
	    if (s.contains(item)) {
		int index = personal.getResource(ptop).getProperty(RSS.items).getSeq().indexOf(item);
		// remove it if it is
		personal.getResource(ptop).getProperty(RSS.items).getSeq().remove(index);
		session.setAttribute("personal", personal);
	    }
	} catch (Exception e) {
	    System.out.println(e);
	}
    }
}
