/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
 *
 * Licensed 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.
 */

var path = require('path');
var cp = require('child_process');
var mkdirp = require('mkdirp');
var Q = require('q');
var sh = require('execSync');

var argparse = require('argparse');
var parser = new argparse.ArgumentParser({
	addHelp : true,
	description : "tiny web operation"
});
parser.addArgument(['--check'],{help : "check the existence of tinyweb on device.if exists,launch it ,if not,install it",action: 'storeTrue'});
parser.addArgument(['--purge'],{help : "clean up tinyweb resources from TIZEN device",action: 'storeTrue'});
parser.addArgument(['--sdbPath'], {help : "the sdb path included in the installed tizen sdk",defaultValue : 'sdb'});
parser.addArgument(['--targetId'], {help : "the targetId"});
parser.addArgument(['--baseDir'], {help : "tinyweb dir"});
var args = parser.parseArgs();
var sdbPath = args.sdbPath;
var targetId = args.targetId ;
var baseDir = args.baseDir;;
var sdbSerno = sdbPath + "  -s  "+ targetId;
//var DEV_ARCH = "arm";


function checkTinyweb() {
	console.log("Check 'TinyWeb' Please wait...");
	
	var rootOnCmd = sdbSerno +' root on';
	exec(rootOnCmd).then(function (data){
		var cmd = sdbSerno + " shell \"ls /opt/home/developer/ | grep tinyweb\" "
		return exec(cmd)
	}).then(function (data){
		if(data){
			return killProcess("tinyweb");
		}else{
			console.log("Install 'TinyWeb' on target... ");
			return installTinyweb();
		}
	}).then(function (data){
		return launchTinyweb();
	}).then(function (data){
		if(data){
			console.log("Active TinyWeb process successfully.");
			portForward();
		}else{
			console.log("Active TinyWeb process failed.");
		}
	}).fail(function (error) {
	    console.log("error occured: " + error);
	});
}

function portForward(){
	exec(sdbSerno+" forward tcp:8082 tcp:8082");
	exec(sdbSerno+" forward tcp:8085 tcp:8085");
}

function launchTinyweb(){
	var dpath = sh.exec(sdbSerno + ' shell \"printenv PATH\"');
	//console.log("before start tinyweb");
	var launchCmd = sdbSerno +' shell "env LD_LIBRARY_PATH=/opt/home/developer PATH=' + dpath.stdout.trim() + ':/opt/home/developer tinyweb -ssl_certificate /opt/home/developer/server.pem -document_root /opt/usr/media/tct/ -listening_ports 80,8080,8081,8082,8085,8443s; sleep 3s > /dev/null 2>&1 " '
	
	function checkLaunch(){
		var checkLaunchCmd = sdbSerno + ' shell "ps aux | grep tinyweb | grep -v grep"'
		return exec(checkLaunchCmd);
	}
	
	return exec(launchCmd).then(function (data){
		return checkLaunch();
	},function (error){
		return checkLaunch();
	})
}

function installTinyweb(){
	console.log("Install tinyweb. Please wait...");
	
	var	DEV_ARCH =	getDeviceArch();
	console.log("DEV_ARCH==="+DEV_ARCH);

	var resourceName = ["tinyweb","cgi-getcookie","cgi-getfield","libmongoose.so","echo.so","server.pem"];
	var resourcePushCmd =[];
	for(var i =0 ;i<resourceName.length ;i++){
		var resourcePath = path.join(baseDir,DEV_ARCH,resourceName[i]);
		resourcePushCmd[i]= sdbSerno + ' push ' + resourcePath + ' /opt/home/developer/';
	}
	resourcePushCmd.push(sdbSerno +' shell "chmod a+x /opt/home/developer/tinyweb > /dev/null 2>&1 " ');
	resourcePushCmd.push(sdbSerno +' shell "chmod a+x /opt/home/developer/cgi-getcookie > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "chmod a+x /opt/home/developer/cgi-getfield > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "chmod 666 /opt/home/developer/libmongoose.so > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "chmod 666 /opt/home/developer/echo.so > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "chmod 666 /opt/home/developer/server.pem > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "ln -s /usr/lib/libssl.so.1.0.0 /opt/home/developer/libssl.so > /dev/null 2>&1"');
	resourcePushCmd.push(sdbSerno +' shell "ln -s /usr/lib/libcrypto.so.1.0.0 /opt/home/developer/libcrypto.so > /dev/null 2>&1"');
	resourcePushCmd.push(sdbSerno +' shell "mkdir -p /opt/usr/media/tct/ > /dev/null 2>&1 " ');
	
	for(var i =0 ;i<resourcePushCmd.length ;i++){
		var result =sh.exec(resourcePushCmd[i]);
		if(result.stdout){
			console.log(result.stdout);
		}
	}
	console.log("Install is over");
	return "";
}

function getDeviceArch(){
	var	archCmd = sdbSerno +' shell  "uname -m" '  ;	
	var result = sh.exec(archCmd);
	
	if(result.hasOwnProperty("stdout") ){
	
		var arch_str = result.stdout.trim();
				
		if(arch_str.indexOf("i686")>=0){			
			return  "ia";
		}else if(arch_str.indexOf("arm")){
			return "arm";
		}else{
			console.log("unsupported arch type :"+arch_str);
			return "arm" ;
		}	
	}else{
		console.log("Failed to get device cpu_arch type");
		return "arm";
	}
}

function killProcess(processName){
	var cmd = sdbSerno +" shell \"ps aux | grep " + processName + " | grep -v grep | awk '{print $2}' \""
	return exec(cmd).then(function (data){
		if(data){
			var killCmd= sdbSerno + ' shell \"kill -9 ' +  data + ' > /dev/null 2>&1 \"'
			return exec(killCmd);
		}else{
			var noProcess = "No process of tinyweb activated";
			console.log(noProcess);
			return noProcess;
		}
	})
}

function purge(){
	killProcess("tinyweb").fin(function (){
		var remove= [
		             sdbSerno +' shell "rm -f /opt/home/developer/server.pem > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f /opt/home/developer/tinyweb > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f /opt/home/developer/cgi-getcookie > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f /opt/home/developer/cgi-getfield > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f /opt/home/developer/libmongoose.so > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f /opt/home/developer/echo.so > /dev/null 2>&1 "'
		     	];
		     	
     	for(var i =0 ;i<remove.length ;i++){
     		var result =sh.exec(remove[i]);
     		if(result.stdout){
     			console.log(result.stdout);
     		}
     	}		
	});
	
}

function exec(command) {

	var deferred = Q.defer();

	//console.log("+", command);

	var proc = cp.exec(command,{timeout: 10000},function (error, stdout, stderr) {
		if (error !== null) {
			deferred.reject(error);
		}
		//console.log("- ["+stdout.trim()+"]");
		deferred.resolve(stdout.trim());
		if(stderr){
			console.log('stderr: [' + stderr+"]");
		}
		
	});

	//new Error(command + " " + args.join(" ") + " in " + cwd + " failed with code " + code);

	return deferred.promise;
};

if (args.check) {
	checkTinyweb();
}

if (args.purge) {
	purge();
}
