/*
 * 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.lang3.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);
	}
}
