/*
 * 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.apache.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.openmeetings.OpenmeetingsVariables;
import org.apache.openmeetings.data.basic.FieldManager;
import org.apache.openmeetings.data.basic.SessiondataDao;
import org.apache.openmeetings.data.basic.dao.ConfigurationDao;
import org.apache.openmeetings.persistence.beans.room.Client;
import org.apache.openmeetings.session.ISessionManager;
import org.apache.openmeetings.utils.OmFileHelper;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ScreenController {
	private static final Logger log = Red5LoggerFactory.getLogger(
			ScreenController.class, OpenmeetingsVariables.webAppRootKey);

	@Autowired
	private ISessionManager sessionManager;
	@Autowired
	public SessiondataDao sessiondataDao;
	@Autowired
	public ConfigurationDao configurationDao;
	@Autowired
	public FieldManager fieldManager;

	private enum ConnectionType {
		rtmp
		, rtmps
		, rtmpt
	}
	
	private String getLabels(Long language_id, int ... ids) {
		StringBuilder result = new StringBuilder();
		boolean delim = false;
		for (int id : ids) {
			if (delim) {
				result.append(';');
			}
			result.append(fieldManager.getFieldByIdAndLanguage((long)id, language_id).getValue());
			delim = true;
		}
		return result.toString();
	}
	
    @RequestMapping(value = "/screen.upload")
	public void handleRequest(HttpServletRequest request,
			HttpServletResponse response) {
		try {
			String sid = request.getParameter("sid");
			Long users_id = sessiondataDao.checkSession(sid);
			String publicSID = request.getParameter("publicSID");
			if (publicSID == null) {
				throw new Exception("publicSID is empty: " + publicSID);
			}
			if (users_id == 0) {
				//checkSession will return 0 in case of invalid session
				throw new Exception("Request from invalid user " + users_id);
			}

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

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

			String rtmphostlocal = request.getParameter("rtmphostlocal");
			if (rtmphostlocal == null) {
				throw new Exception("rtmphostlocal is empty: " + rtmphostlocal);
			}
			
			String baseURL = request.getParameter("baseurl");
			if (baseURL == null) {
				throw new Exception("baseurl is empty: " + baseURL);
			}
			log.debug("language_id :: " + language_id);
			String label_sharer = "Sharer";

			try {
				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);
			}
			log.debug("Creating JNLP Template for TCP solution");

			//libs
			StringBuilder libs = new StringBuilder();
			File screenShareDir = OmFileHelper.getScreenSharingDir();
			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");
			}
			log.debug("RTMP Sharer labels :: " + label_sharer);

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

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

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

			String port = request.getParameter("port");
			if (port == null) {
				throw new Exception("port is empty: ");
			}
			Client rc = sessionManager.getClientByPublicSID(publicSID, false, null);
			if (rc == null) {
				throw new Exception("port is empty: ");
			}
			Long roomId = rc.getRoom_id();
			boolean allowRecording = rc.getAllowRecording()
				&& (0 == sessionManager.getRecordingCount(roomId));
			boolean allowPublishing = (0 == sessionManager
					.getPublishingCount(roomId));
			
			Context ctx = new VelocityContext();
			ctx.put("APP_NAME", configurationDao.getAppName());
			ctx.put("PUBLIC_SID", publicSID);
			ctx.put("LABELSHARER", label_sharer);
			addKeystore(ctx);
			ctx.put("LIBRARIES", libs);
			ctx.put("organization_id", orgIdAsString);
			ctx.put("startUpClass", startUpClass);
			ctx.put("codebase", baseURL + OmFileHelper.SCREENSHARING_DIR);
			ctx.put("red5-host", rtmphostlocal);
			ctx.put("red5-app", OpenmeetingsVariables.webAppRootKey + "/" + roomId);
			ctx.put("default_quality_screensharing",
					configurationDao
						.getConfValue("default.quality.screensharing", String.class, "1"));
			//invited guest does not have valid user_id (have user_id == -1)
			ctx.put("user_id", users_id);
			ctx.put("port", port);
			ctx.put("allowRecording", allowRecording);
			ctx.put("allowPublishing", allowPublishing);

			String requestedFile = StringUtils.deleteWhitespace(domain + "_" + roomId) + ".jnlp";
			response.setContentType("application/x-java-jnlp-file");
			response.setCharacterEncoding("UTF-8");
			response.setHeader("Content-Disposition",
					"Inline; filename=\"" + requestedFile + "\"");

			VelocityEngine ve = new VelocityEngine();
			ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); 
			ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
			
			ve.mergeTemplate(
				"screenshare.vm"
				, "UTF-8"
				, ctx
				, response.getWriter());
		} catch (Exception er) {
			log.error("[ScreenController]", er);
		}
	}

	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 {
			File conf = new File(OmFileHelper.getRootDir(), "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);
	}
}
