/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.openmeetings.servlet.outputhandler;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;
import org.openmeetings.app.OpenmeetingsVariables;
import org.openmeetings.app.data.basic.Configurationmanagement;
import org.openmeetings.app.data.basic.Fieldmanagment;
import org.openmeetings.app.data.basic.Sessionmanagement;
import org.openmeetings.app.persistence.beans.basic.Configuration;
import org.openmeetings.app.remote.red5.ScopeApplicationAdapter;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class ScreenRequestHandler extends VelocityViewServlet {
	private static final long serialVersionUID = 2381722235536488913L;
	private static final Logger log = Red5LoggerFactory.getLogger(
			ScreenRequestHandler.class, OpenmeetingsVariables.webAppRootKey);

	public Sessionmanagement getSessionManagement() {
		try {
			if (ScopeApplicationAdapter.initComplete) {
				ApplicationContext context = WebApplicationContextUtils
						.getWebApplicationContext(getServletContext());
				return context.getBean(Sessionmanagement.class);
			}
		} catch (Exception err) {
			log.error("[getSessionManagement]", err);
		}
		return null;
	}

	public Configurationmanagement getCfgManagement() {
		try {
			if (ScopeApplicationAdapter.initComplete) {
				ApplicationContext context = WebApplicationContextUtils
						.getWebApplicationContext(getServletContext());
				return context.getBean(Configurationmanagement.class);
			}
		} catch (Exception err) {
			log.error("[getCfgManagement]", err);
		}
		return null;
	}

	public Fieldmanagment getFieldmanagment() {
		try {
			if (ScopeApplicationAdapter.initComplete) {
				ApplicationContext context = WebApplicationContextUtils
						.getWebApplicationContext(getServletContext());
				return context.getBean(Fieldmanagment.class);
			}
		} catch (Exception err) {
			log.error("[getFieldmanagment]", err);
		}
		return null;
	}

	private enum ConnectionType {
		rtmp
		, rtmps
		, rtmpt
	}
	
	private String getLabels(Long language_id, int ... ids) {
		Fieldmanagment fieldmanagment = getFieldmanagment();
		StringBuilder result = new StringBuilder();
		boolean delim = false;
		for (int id : ids) {
			if (delim) {
				result.append(';');
			}
			result.append(fieldmanagment.getFieldByIdAndLanguage((long)id, language_id).getValue());
			delim = true;
		}
		return result.toString();
	}
	
	@Override
	public Template handleRequest(HttpServletRequest httpServletRequest,
			HttpServletResponse httpServletResponse, Context ctx) {

		try {
			if (getSessionManagement() == null) {
				return getVelocityView().getVelocityEngine().getTemplate(
						"booting.vm");
			}

			String sid = httpServletRequest.getParameter("sid");
			if (sid == null) {
				sid = "default";
			}
			log.debug("sid: " + sid);

			Long users_id = getSessionManagement().checkSession(sid);
			if (users_id == 0) {
				//checkSession will return 0 in case of invalid session
				throw new Exception("Request from invalid user " + users_id);
			}
			String publicSID = httpServletRequest.getParameter("publicSID");
			if (publicSID == null) {
				throw new Exception("publicSID is empty: " + publicSID);
			}

			String room = httpServletRequest.getParameter("room");
			if (room == null)
				room = "default";

			String domain = httpServletRequest.getParameter("domain");
			if (domain == null) {
				throw new Exception("domain is empty: " + domain);
			}

			String languageAsString = httpServletRequest
					.getParameter("languageAsString");
			if (languageAsString == null) {
				throw new Exception("languageAsString is empty: " + domain);
			}
			Long language_id = Long.parseLong(languageAsString);

			String rtmphostlocal = httpServletRequest
					.getParameter("rtmphostlocal");
			if (rtmphostlocal == null) {
				throw new Exception("rtmphostlocal is empty: " + rtmphostlocal);
			}

			String red5httpport = httpServletRequest
					.getParameter("red5httpport");
			if (red5httpport == null) {
				throw new Exception("red5httpport is empty: " + red5httpport);
			}

			String record = httpServletRequest.getParameter("record");
			if (record == null) {
				throw new Exception("recorder is empty: ");
			}

			String httpRootKey = httpServletRequest.getParameter("httpRootKey");
			if (httpRootKey == null) {
				throw new Exception("httpRootKey is empty could not start sharer");
			}

			String baseURL = httpServletRequest.getScheme() + "://" + rtmphostlocal + ":" + red5httpport
					+ httpRootKey;

			// make a complete name out of domain(organisation) + roomname
			String roomName = domain + "_" + room;
			// trim whitespaces cause it is a directory name
			roomName = StringUtils.deleteWhitespace(roomName);

			ctx.put("rtmphostlocal", rtmphostlocal); // rtmphostlocal
			ctx.put("red5httpport", red5httpport); // red5httpport

			log.debug("httpRootKey " + httpRootKey);

			String codebase = baseURL + "screen";

			ctx.put("codebase", codebase);

			String httpSharerURL = baseURL + "ScreenServlet";

			ctx.put("webAppRootKey", httpRootKey);
			ctx.put("httpSharerURL", httpSharerURL);

			ctx.put("APP_NAME", getCfgManagement().getAppName());
			ctx.put("SID", sid);
			ctx.put("ROOM", room);
			ctx.put("DOMAIN", domain);
			ctx.put("PUBLIC_SID", publicSID);
			ctx.put("RECORDER", record);

			String requestedFile = roomName + ".jnlp";
			httpServletResponse.setContentType("application/x-java-jnlp-file");
			httpServletResponse.setHeader("Content-Disposition",
					"Inline; filename=\"" + requestedFile + "\"");


			log.debug("language_id :: " + language_id);
			String label_viewer = "Viewer";
			String label_sharer = "Sharer";

			try {
				label_viewer = getLabels(language_id, 728, 729, 736, 742);

				label_sharer = getLabels(language_id
					,  730,  731,  732,  733,  734
					,  735,  737,  738,  739,  740
					,  741,  742,  844,  869,  870
					,  871,  872,  878, 1089, 1090
					, 1091, 1092, 1093, 1465, 1466
					, 1467, 1468, 1469, 1470, 1471
					, 1472, 1473, 1474, 1475, 1476
					, 1477);
			} catch (Exception e) {
				log.error("Error resolving Language labels : ", e);
			}

			ctx.put("LABELVIEWER", label_viewer);
			ctx.put("LABELSHARER", label_sharer);

			log.debug("Creating JNLP Template for TCP solution");

			try {
				final String screenShareDirName = "screensharing";
				//libs
				StringBuilder libs = new StringBuilder();
				File screenShareDir = new File(ScopeApplicationAdapter.webAppPath, screenShareDirName);
				for (File jar : screenShareDir.listFiles(new FileFilter() {
					public boolean accept(File pathname) {
						return pathname.getName().endsWith(".jar");
					}
				})) {
					libs.append("\t\t<jar href=\"").append(jar.getName()).append("\"/>\n");
				}
				addKeystore(ctx);
				ctx.put("LIBRARIES", libs);
				log.debug("RTMP Sharer labels :: " + label_sharer);

				codebase = baseURL + screenShareDirName;

				ConnectionType conType = ConnectionType
						.valueOf(httpServletRequest
								.getParameter("connectionType"));

				String startUpClass;
				switch (conType) {
				case rtmp:
					startUpClass = "org.openmeetings.screen.webstart.RTMPScreenShare";
					break;
				case rtmps:
					startUpClass = "org.openmeetings.screen.webstart.RTMPSScreenShare";
					break;
				case rtmpt:
					startUpClass = "org.openmeetings.screen.webstart.RTMPTScreenShare";
					break;
				default:
					throw new Exception("Unknown connection type");
				}

				String orgIdAsString = httpServletRequest
						.getParameter("organization_id");
				if (orgIdAsString == null) {
					throw new Exception(
							"orgIdAsString is empty could not start sharer");
				}

				ctx.put("organization_id", orgIdAsString);

				ctx.put("startUpClass", startUpClass);
				ctx.put("codebase", codebase);
				ctx.put("red5-host", rtmphostlocal);
				ctx.put("red5-app", OpenmeetingsVariables.webAppRootKey + "/"
						+ room);

				Configuration configuration = getCfgManagement().getConfKey(3L,
						"default.quality.screensharing");
				String default_quality_screensharing = "1";
				if (configuration != null) {
					default_quality_screensharing = configuration
							.getConf_value();
				}

				ctx.put("default_quality_screensharing",
						default_quality_screensharing);

				//invited guest does not have valid user_id (have user_id == -1)
				ctx.put("user_id", users_id);

				String port = httpServletRequest.getParameter("port");
				if (port == null) {
					throw new Exception("port is empty: ");
				}
				ctx.put("port", port);

				String allowRecording = httpServletRequest
						.getParameter("allowRecording");
				if (allowRecording == null) {
					throw new Exception("allowRecording is empty: ");
				}
				ctx.put("allowRecording", allowRecording);

			} catch (Exception e) {
				log.error("invalid configuration value for key screen_viewer!");
			}

			String template = "screenshare.vm";

			return getVelocityView().getVelocityEngine().getTemplate(template);

		} catch (Exception er) {
			log.error("[ScreenRequestHandler]", er);
			System.out.println("Error downloading: " + er);
		}
		return null;
	}

	private StringBuilder addArgument(StringBuilder sb, Object arg) {
		return sb.append("\t\t<argument>").append(arg).append("</argument>\n");
	}
	
	private void addKeystore(Context ctx) {
		log.debug("RTMP Sharer Keystore :: start");
		StringBuilder sb = new StringBuilder();
		FileInputStream fis = null;
		try {
			//FIXME hack !!!!
			File root = new File(ScopeApplicationAdapter.webAppPath).getParentFile().getParentFile();
			File conf = new File(root, "conf");

			File keyStore = new File(conf, "keystore.screen");
			if (keyStore.exists()) {
				Properties red5Props = new Properties();
				red5Props.load(new FileInputStream(new File(conf, "red5.properties")));
				
				byte keyBytes[] = new byte[(int)keyStore.length()];
				fis = new FileInputStream(keyStore);
				fis.read(keyBytes);
				
				sb = addArgument(addArgument(sb, Hex.encodeHexString(keyBytes)), red5Props.getProperty("rtmps.keystorepass"));
				
				/*
				KeyStore ksIn = KeyStore.getInstance(KeyStore.getDefaultType());
				ksIn.load(new FileInputStream(keyStore), red5Props.getProperty("rtmps.keystorepass").toCharArray());
				ByteArrayInputStream bin = new ByteArrayInputStream()
				
				byte fileContent[] = new byte[(int)file.length()];
				sb = addArgument(sb, Object arg)
				ctx.put("$KEYSTORE", users_id);
				/*
				KeyStore ksOut = KeyStore.getInstance(KeyStore.getDefaultType());
				for (Certificate cert : ksIn.getCertificateChain("red5")) {
					PublicKey pub = cert.getPublicKey();
					TrustedCertificateEntry tce = new TrustedCertificateEntry(cert);
					tce.
				}
				*/
			}
		} catch (Exception e) {
			//no op
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// no op
				}
			}
		}
		ctx.put("KEYSTORE", sb);
	}
}
