/*
 * 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";

var installPath;
var targetVersion;

initTargetPlatformInfo();

function checkTinyweb() {
	console.log("Check 'TinyWeb' Please wait...");
	
	var rootOnCmd;
    if(targetVersion == "v3.0") {
        rootOnCmd= sdbSerno +' root off';
    } else if(targetVersion == "v2.x") {
        rootOnCmd= sdbSerno +' root on';
    } else {
        console.log("error occured: Unknown version");
        return;
    }

	exec(rootOnCmd).then(function (data){
		var cmd = sdbSerno + " shell \"ls "+ installPath + " | 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");
}

function launchTinyweb(){
	var dpath = sh.exec(sdbSerno + ' shell \"printenv PATH\"');
	//console.log("before start tinyweb");

    var launchCmd = sdbSerno +' shell "env LD_LIBRARY_PATH=' + installPath + ' PATH=' + dpath.stdout.trim() + ':'+ installPath + ' tinyweb -ssl_certificate '+ installPath + 'server.pem -document_root ' + installPath + 'tct/ -listening_ports 8080,8081,8082,8085,8443,9000; 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 + ' '+ installPath + '';
	}
	resourcePushCmd.push(sdbSerno +' shell "chmod a+x ' + installPath + 'tinyweb > /dev/null 2>&1 " ');
	resourcePushCmd.push(sdbSerno +' shell "chmod a+x ' + installPath + 'cgi-getcookie > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "chmod a+x ' + installPath + 'cgi-getfield > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "chmod 666 ' + installPath + 'libmongoose.so > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "chmod 666 ' + installPath + 'echo.so > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "chmod 666 ' + installPath + 'server.pem > /dev/null 2>&1 "');
	resourcePushCmd.push(sdbSerno +' shell "ln -s /usr/lib/libssl.so.1.0.0 ' + installPath + 'libssl.so > /dev/null 2>&1"');
	resourcePushCmd.push(sdbSerno +' shell "ln -s /usr/lib/libcrypto.so.1.0.0 ' + installPath + 'libcrypto.so > /dev/null 2>&1"');
	resourcePushCmd.push(sdbSerno +' shell "mkdir -p ' + installPath + '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 initTargetPlatformInfo(){
	var	cmd = sdbSerno +' shell "ls /opt/usr/home/owner/" '  ;
	var result = sh.exec(cmd);

	if(result.hasOwnProperty("stdout")
            && result.stdout.indexOf("No such file or directory") < 0){
        targetVersion="v3.0";
        installPath="/opt/usr/home/owner/";
	}else{
        cmd = sdbSerno +' shell "ls /opt/home/developer/" '  ;
        result = sh.exec(cmd);

        if(result.hasOwnProperty("stdout")
                && result.stdout.indexOf("No such file or directory") < 0){
            targetVersion="v2.x";
            installPath="/opt/home/developer/";
        } else {
            console.log("Unknown Target Version");
            targetVersion="Unknown";
            installPath="Unknwon";
        }
	}
}

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 ' + installPath + 'server.pem > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f ' + installPath + 'tinyweb > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f ' + installPath + 'cgi-getcookie > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f ' + installPath + 'cgi-getfield > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f ' + installPath + 'libmongoose.so > /dev/null 2>&1 "',
		             sdbSerno +' shell "rm -f ' + installPath + '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();
}
