/*
 * 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 static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSHARING_ALLOW_REMOTE;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSHARING_FPS;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSHARING_FPS_SHOW;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SCREENSHARING_QUALITY;
import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;

import java.io.File;
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.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.label.LabelDao;
import org.apache.openmeetings.db.dao.room.RoomDao;
import org.apache.openmeetings.db.dao.server.ISessionManager;
import org.apache.openmeetings.db.dao.server.SessiondataDao;
import org.apache.openmeetings.db.entity.room.Client;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.util.OmFileHelper;
import org.apache.openmeetings.util.OpenmeetingsVariables;
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.log.Log4JLogChute;
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, webAppRootKey);

	@Autowired
	private ISessionManager sessionManager;
	@Autowired
	public SessiondataDao sessiondataDao;
	@Autowired
	public ConfigurationDao cfgDao;
	@Autowired
	public LabelDao labelDao;
	@Autowired
	public RoomDao roomDao;

	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(labelDao.getString((long)id, language_id));
			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, 1589, 1598, 1078);
			} catch (Exception e) {
				log.error("Error resolving Language labels : ", e);
			}
			log.debug("Creating JNLP Template for TCP solution");

			log.debug("RTMP Sharer labels :: " + label_sharer);

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

			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();
			if (roomId == null) {
				throw new Exception("Client has no room " + rc);
			}
			Room room = roomDao.get(roomId);
			boolean allowRecording = room.isAllowRecording() && rc.isAllowRecording() && (0 == sessionManager.getRecordingCount(roomId));
			boolean allowPublishing = (0 == sessionManager.getPublishingCount(roomId));
			
			Context ctx = new VelocityContext();
			ctx.put("codebase", baseURL + OmFileHelper.SCREENSHARING_DIR);
			ctx.put("APP_NAME", cfgDao.getAppName());
			ctx.put("protocol", conType.name());
			ctx.put("host", rtmphostlocal);
			ctx.put("port", port);
			ctx.put("app", OpenmeetingsVariables.webAppRootKey + "/" + roomId);
			ctx.put("userId", users_id);
			ctx.put("publicSid", publicSID);
			ctx.put("labels", label_sharer);
			ctx.put("defaultQuality", cfgDao.getConfValue(CONFIG_SCREENSHARING_QUALITY, String.class, "1"));
			ctx.put("defaultFps", cfgDao.getConfValue(CONFIG_SCREENSHARING_FPS, String.class, "10"));
			ctx.put("showFps", cfgDao.getConfValue(CONFIG_SCREENSHARING_FPS_SHOW, Boolean.class, "true"));
			ctx.put("allowRemote", cfgDao.getConfValue(CONFIG_SCREENSHARING_ALLOW_REMOTE, Boolean.class, "true"));
			ctx.put("allowRecording", allowRecording);
			ctx.put("allowPublishing", allowPublishing);
			addKeystore(ctx);

			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.setProperty(Log4JLogChute.RUNTIME_LOG_LOG4J_LOGGER, Log4JLogChute.class.getName()); 
			
			ve.mergeTemplate(
				"screenshare.vm"
				, "UTF-8"
				, ctx
				, response.getWriter());
		} catch (Exception er) {
			log.error("[ScreenController]", er);
		}
	}

	private void addKeystore(Context ctx) {
		log.debug("RTMP Sharer Keystore :: start");
		String keystore = "--dummy--", password = "--dummy--";
		FileInputStream fis = null, ris = null;
		try {
			File conf = new File(OmFileHelper.getRootDir(), "conf");

			File keyStore = new File(conf, "keystore.screen");
			if (keyStore.exists()) {
				Properties red5Props = new Properties();
				ris = new FileInputStream(new File(conf, "red5.properties"));
				red5Props.load(ris);
				
				byte keyBytes[] = new byte[(int)keyStore.length()];
				fis = new FileInputStream(keyStore);
				fis.read(keyBytes);
				
				keystore = Hex.encodeHexString(keyBytes);
				password = red5Props.getProperty("rtmps.screen.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
				}
			}
			if (ris != null) {
				try {
					ris.close();
				} catch (IOException e) {
					// no op
				}
			}
		}
		ctx.put("keystore", keystore);
		ctx.put("password", password);
	}
}
