package samples.webcenter.portlets.wiki;

import java.io.IOException;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.PortletContext;

import javax.portlet.PortletRequestDispatcher;

import samples.webcenter.services.wiki.*;
import samples.webcenter.services.wiki.remote.*;

public class WikiPortlet extends GenericPortlet {

	public static String URL = "url";
	public static String SCOPE = "scope"; // Wiki scope/domain to use
	public static String PAGE = "page"; // Page to display
	public static String MAX_PAGES = "max_pages"; // Page to display
	public static String TEMPLATE = "template"; // Name of template to use
	
	public static String[] prefNames = {
		URL,
		SCOPE,
		PAGE,
		MAX_PAGES,
		TEMPLATE
	};
	
	public WikiServiceProxy getWikiServiceProxy(PortletRequest request, PortletResponse response) {

		java.security.Principal principal = request.getUserPrincipal();
		
		String username = principal != null ? principal.getName() : "anonymous";
		String passcode = "owCwIKi";
		String key = null;
		
		//PortletPreferences prefs = request.getPreferences();
		String url = (String) request.getPortletSession().getAttribute(URL);
		String wikiProxyUrl = url != null ? url + "/owc_wiki/services/WikiRemoteService" : null;
		
		WikiServiceProxy wikiProxy = null;
		
		try {
			wikiProxy = new WikiServiceProxy(wikiProxyUrl);
		} catch (Exception e) {
			request.setAttribute("error_type", "invalid_url");			
			request.getPortletSession().removeAttribute("wiki_key");
		}
		
		try {
			key = wikiProxy.login(username, passcode);
			request.getPortletSession().setAttribute("wiki_key", key);
			return wikiProxy;
		} catch (Exception e) {
			//e.printStackTrace();

			if (e.getMessage() != null) {
				if (e.getMessage().contains("404")) {
					request.setAttribute("error_type", "invalid_service");
				} else if (e.getMessage().toLowerCase().contains("connection refused")) {
					request.setAttribute("error_type", "invalid_url");			
				} else if (e.getMessage().toLowerCase().contains("no such user")) {
					request.setAttribute("error_type", "invalid_user");			
				} else {
					request.setAttribute("error_type", "other");
				}
			}
			request.getPortletSession().removeAttribute("wiki_key");
		}
		
		return null;
	}
	
	public void _doIt(RenderRequest request, RenderResponse response, boolean getWikiData)
		throws PortletException, IOException {
	
		response.setContentType("text/html");
		
        request.removeAttribute("error_type");
        
		// Make preferences available to JSPs
		PortletPreferences prefs = request.getPreferences();
		PortletSession session = request.getPortletSession();
		String name = null;
		String value = null;
		
		for (int i = 0; i < prefNames.length; i++) {
			name = prefNames[i];

			value = prefs.getValue(name, null);
			
			if (value == null) {
				value = (String) session.getAttribute(name);
			} else {
				session.setAttribute(name, value);
			}
			
			request.setAttribute("wiki_" + name, value);
		}
		
		if (getWikiData == true) {
			WikiServiceProxy wikiProxy = this.getWikiServiceProxy(request, response);
			
            if (wikiProxy != null) {
            	String key = (String) request.getPortletSession().getAttribute("wiki_key");
				
            	
				try {
					DomainInfo[] allDomainInfo = wikiProxy.getAllDomainInfo(-1, 0, key);
					request.setAttribute("all_domain_info", allDomainInfo);
				} catch (Exception e) {
					//e.printStackTrace();
					request.removeAttribute("all_domain_info");
				}
				
				//String url = (String) session.getAttribute(URL);
				//url = url != null ? url : "http://" + request.getServerName() + ":" + request.getServerPort();
				
				String scope = (String) session.getAttribute(SCOPE);
				scope = scope != null ? scope : "";
				String pageName = (String) session.getAttribute(PAGE);
				pageName = (pageName != null && !"".equals(pageName)) ? pageName : "WelcomePage";

				String m = (String) session.getAttribute(MAX_PAGES);
				int max = 9999;
				try {
					max = Integer.parseInt(m);
				} catch (Exception e) {
					//e.printStackTrace();
				}
				if (max <= 0) {
					max = 1;
					request.setAttribute("wiki_max_pages", max);
				}
				
				try {
					PageInfo[] allPageInfo = wikiProxy.getAllPageInfo(scope, max, 0, key);
					request.setAttribute("all_page_info", allPageInfo);

					PageInfo info = wikiProxy.getPageInfo(scope, pageName, key);
					request.setAttribute("page_info", info);
					
					String source = wikiProxy.getRenderedPage(scope, pageName, key);
					request.setAttribute("page_markup", source);

					String markup = wikiProxy.getPlainPage(scope, pageName, key);
					request.setAttribute("page_source", markup);
					
		        } catch (Exception e) {
					//e.printStackTrace();

					String msg = e.getMessage();
					if (msg.indexOf("domain") > 0) {
						request.setAttribute("error_type", "invalid_domain");
					} else if (msg.indexOf("page") > 0) {
						request.setAttribute("error_type", "invalid_page");
					} else {
						request.setAttribute("error_type", "other");
					}
		        }
			}
		}
		
		// Search results are in the session...
		request.setAttribute("search_results", request.getPortletSession().getAttribute("search_results"));
		request.getPortletSession().removeAttribute("search_results");
		
		request.setAttribute("wiki_search_text", request.getPortletSession().getAttribute("wiki_search_text"));
		request.getPortletSession().removeAttribute("wiki_search_text");
		
		request.setAttribute("wiki_create", request.getPortletSession().getAttribute("wiki_create"));
		request.getPortletSession().removeAttribute("wiki_create");

		request.setAttribute("wiki_settings", request.getPortletSession().getAttribute("wiki_settings"));
		request.getPortletSession().removeAttribute("wiki_settings");
	}
	
	public void doView(RenderRequest request, RenderResponse response)
		throws PortletException, IOException {
		
	    this._doIt(request, response, true);
	    PortletContext context = getPortletContext();
	    PortletRequestDispatcher rd = context.getRequestDispatcher("/wiki/wikiView.jsp");
	    rd.include(request, response);                
	}
	
	public void doEdit(RenderRequest request, RenderResponse response)
		throws PortletException, java.io.IOException {

	    this._doIt(request, response, true);
	    PortletContext context = getPortletContext();
	    PortletRequestDispatcher rd = context.getRequestDispatcher("/wiki/wikiEdit.jsp");
	    rd.include(request, response);                
	}

	public void doHelp(RenderRequest request, RenderResponse response)
		throws PortletException, java.io.IOException {

	    this._doIt(request, response, true);
	    PortletContext context = getPortletContext();
	    PortletRequestDispatcher rd = context.getRequestDispatcher("/wiki/wikiHelp.jsp");
	    rd.include(request, response);                
	}
	
	public void processAction(ActionRequest request, ActionResponse response)
		throws PortletException, java.io.IOException {

		if (request.getPortletMode().equals(PortletMode.VIEW)) {

			this.parsePrefs(request, response);

			request.getPortletSession().setAttribute("wiki_create", request.getParameter("wiki_create"));
			
			String action = request.getParameter("page_action");
			if (action != null) {
				if ("update".equals(action)) {
					this.updateWikiPage(request, response);
				} else if ("create".equals(action)) {
					this.createWikiPage(request, response);
				} else if ("delete".equals(action)) {
					this.deleteWikiPage(request, response);					
				} else if ("search".equals(action)) {
					this.searchWiki(request, response);					
				} else if ("create_domain".equals(action)) {
					this.createDomain(request, response);					
				} else if ("settings".equals(action)) {
					request.getPortletSession().setAttribute("wiki_settings", "true");
				}
			}
		} else {
			if (request.getPortletMode().equals(PortletMode.EDIT)) {
				this.parsePrefs(request, response);
				response.setPortletMode(PortletMode.VIEW);
			}
		}
	}

	public void createDomain(PortletRequest request, PortletResponse response)
		throws PortletException, java.io.IOException {

		String scope = request.getParameter("wiki_scope");
		String description = "";
		String name = request.getParameter("page_name");
	
		PortletPreferences prefs = request.getPreferences();

		WikiServiceProxy wikiProxy = this.getWikiServiceProxy(request, response);
	
		if (wikiProxy != null) {
			String key = (String) request.getPortletSession().getAttribute("wiki_key");
			try {
				wikiProxy.createDomain(scope, description, name, key);
				wikiProxy.savePage(scope, name, "", key);
	
				// Set the newly created entry in the prefs
				prefs.setValue(SCOPE, scope);
				request.getPortletSession().setAttribute(SCOPE, scope);
				prefs.setValue(PAGE, name);
				request.getPortletSession().setAttribute(PAGE, name);
				prefs.store();
			} catch (Exception e) {
				//e.printStackTrace();
			}
		}
	}

	public void createWikiPage(PortletRequest request, PortletResponse response)
		throws PortletException, java.io.IOException {

		String content = request.getParameter("page_content");
		content = content != null ? content : "";
		
		String name = request.getParameter("page_name");
		name = name != null ? name : "WelcomePage";
		
		String mode = request.getParameter("page_mode");
		mode = mode != null ? mode : PageEditMode.value3.getValue();

		String type = request.getParameter("page_type");
		type = type != null ? type : PageType.value1.getValue();
		
		PortletPreferences prefs = request.getPreferences();
		String scope = (String) request.getPortletSession().getAttribute(SCOPE);

 		WikiServiceProxy wikiProxy = this.getWikiServiceProxy(request, response);
		
		if (wikiProxy != null) {
			String key = (String) request.getPortletSession().getAttribute("wiki_key");
			try {
				wikiProxy.createPage(scope, name, PageEditMode.fromString(mode), PageType.fromString(type), key);
				wikiProxy.savePage(scope, name, content, key);

				// Set the newly created entry in the prefs
				prefs.setValue(PAGE, name);
				request.getPortletSession().setAttribute(PAGE, name);
				prefs.store();
			} catch (Exception e) {
				//e.printStackTrace();
			}
		}
	}

	public void deleteWikiPage(PortletRequest request, PortletResponse response)
		throws PortletException, java.io.IOException {

		PortletPreferences prefs = request.getPreferences();
		String scope = (String) request.getPortletSession().getAttribute(SCOPE);
		String name = request.getParameter("page_name");

 		WikiServiceProxy wikiProxy = this.getWikiServiceProxy(request, response);
		
		if (wikiProxy != null) {
			String key = (String) request.getPortletSession().getAttribute("wiki_key");
			try {
				wikiProxy.deletePage(scope, name, key);

				PageInfo[] info = wikiProxy.getAllPageInfo(scope, -1, 0, key);
				
				name = info[0].getName();

				// Set the first page in the prefs
				prefs.setValue(PAGE, name);
				request.getPortletSession().setAttribute(PAGE, name);				
				prefs.store();
			} catch (Exception e) {
				//e.printStackTrace();
			}
		}
	}

	public void updateWikiPage(PortletRequest request, PortletResponse response)
		throws PortletException, java.io.IOException {

		String content = request.getParameter("page_content");
		String name = request.getParameter("page_name");

		String scope = (String) request.getPortletSession().getAttribute(SCOPE);

 		WikiServiceProxy wikiProxy = this.getWikiServiceProxy(request, response);
		
		if (wikiProxy != null) {
			String key = (String) request.getPortletSession().getAttribute("wiki_key");
			try {
				wikiProxy.savePage(scope, name, content, key);
			} catch (Exception e) {
				//e.printStackTrace();
			}
		}
	}
	
	public void searchWiki(PortletRequest request, PortletResponse response)
		throws PortletException, java.io.IOException {

		String text = request.getParameter("wiki_search_text");
                request.getPortletSession().setAttribute("wiki_search_text", text);
                
		WikiServiceProxy wikiProxy = this.getWikiServiceProxy(request, response);
		
		if (wikiProxy != null) {
			String key = (String) request.getPortletSession().getAttribute("wiki_key");
			try {
				SearchResult[] results = wikiProxy.search(text, SearchType.wiki, 200, key);
				//request.setAttribute("search_results", results);
				request.getPortletSession().setAttribute("search_results", results);
			} catch (Exception e) {
				//e.printStackTrace();
			}
		}
	}
	
	public void parsePrefs(PortletRequest request, PortletResponse response)
		throws PortletException, java.io.IOException {
	
		PortletPreferences prefs = request.getPreferences();
		String name = null;
		String value = null;
		
		PortletSession session = request.getPortletSession();
		
		for (int i = 0; i < prefNames.length; i++) {
			name = prefNames[i];
			value = request.getParameter("wiki_" + name);
			if (value != null) {
				prefs.setValue(name, value);
				session.setAttribute(name, value);
			}
		}
		
		try {
			prefs.store();
		} catch (Exception e) {
			//e.printStackTrace();
		}
	}

}
