#!/bin/bash

#-----------------------------------------------------------
# $Id: execute.sh 112 2009-03-18 22:36:26Z rosiere $
#-----------------------------------------------------------

#-----[ global variable ]-----------------------------------

#-----[ lock ]----------------------------------------------
function lock ()
{
    lockfile -1 ${1};
}

#-----[ unlock ]--------------------------------------------
function unlock ()
{
    rm -f ${1};
}

#-----[ my_date ]-------------------------------------------
function my_date ()
{
    date +"%F %T";
}

#-----[ execute_usage ]-------------------------------------
function execute_usage ()
{
    echo "Usage     : ${0} work_dir file_cmd file_cpt file_cpu";
    echo "Arguments : ";
    echo " * work_dir   : directory to execute command";
    echo " * file_cmd   : list of command";
    echo " * file_cpt   : file with the index of next command to execute";
    echo " * file_cpu   : tmp file to stock the current index";
    exit;
}

#-----[ execute_test_usage ]--------------------------------
function execute_test_usage ()
{
    if test ${#} -ne 4; then
	execute_usage;
    fi;

    if test ! -d ${1}; then
        echo "Directory ${1} is invalid";
    fi;
}

#-----[ execute ]-------------------------------------------
function execute ()
{
    # test_usage
    execute_test_usage ${*};

    local -a COMMAND;
    local -i CPT_OLD;
    local -i CPT;
    local    WORK_DIR=${1};
    local    FILE_CMD=${2};
    local    FILE_CPT=${3};
    local    FILE_CPU=${4};
    local    LOCK_CPT="${WORK_DIR}/.lock-cpt";
    local    LOCK_CPU="${WORK_DIR}/.lock-cpu";
    local    FILE_CMD="distexe.command";
    local    FILE_OUT="distexe.output";


    # Init CPT if this thread is the first
    lock   ${LOCK_CPT};
    if test ! -s ${FILE_CPT}; then
	echo "0" > ${FILE_CPT};
    fi;
    unlock ${LOCK_CPT};

    # read, line by line, the command file and write in array
    CPT=0;

    while read line; do
	COMMAND[${CPT}]="${line}";
	CPT=$((${CPT}+1));
    done < ${FILE_CMD};

    echo "  * <${HOSTNAME}-$$> {"$(my_date)"} is ready";

    # infinite loop
    CPT_OLD=0;
    CPT=0;

    while test 1; do
	# Take a number
	CPT_OLD=${CPT};

        # Read the index, and increase
	lock   ${LOCK_CPT};
	CPT=$(cat ${FILE_CPT});
	echo "$((${CPT}+1))" > ${FILE_CPT};
	unlock ${LOCK_CPT};

	# test if this number is valid
	if test ${CPT} -ge ${#COMMAND[*]}; then
	    CPT=${#COMMAND[*]};
	fi;

	# test if between the cpt_old and cpt, there are a synchronisation command

#	local -i CPT_SYNC=${CPT}_OLD;
#
#	while test ${CPT}_SYNC -lt ${CPT}; do
#	    if test -z "${COMMAND[${CPT}_SYNC]}"; then
#		echo "  * <${HOSTNAME}-$$> {"$(my_date)"} synchronisation [${CPT}_SYNC]";
#	    fi;
#	    CPT_SYNC=$((${CPT}_SYNC+1));
#	done;

	# test if this number is valid
	if test ${CPT} -eq ${#COMMAND[*]}; then
	    break;
	fi;

	# Test if command is empty !
	if test ! -z "${COMMAND[${CPT}]}"; then
	    local CURREN_DIR=${PWD};
            cd    ${WORK_DIR}         &> /dev/null;
	    mkdir "Task_${CPT}"       &> /dev/null;
	    cd    "Task_${CPT}"       &> /dev/null;
	    echo "  * <${HOSTNAME}-$$> {"$(my_date)"} execute command [${CPT}] : ${COMMAND[${CPT}]}";
	    echo "${COMMAND[${CPT}]}"  >  ${FILE_CMD};
#	    chmod +x                      ${FILE_CMD};
	    eval "${COMMAND[${CPT}]}" &>  ${FILE_OUT};
	    cd    ${CURREN_DIR}       &> /dev/null;
	fi;
    done;

    echo "  * <${HOSTNAME}-$$> {"$(my_date)"} is done";

    lock   ${LOCK_CPU};
    CPT=$(cat ${FILE_CPU});    # read  the      index
    CPT=$((${CPT}-1));
    echo "${CPT}" > ${FILE_CPU}; # write the next index
    unlock ${LOCK_CPU};
    
    if test ${CPT} -eq 0; then
	echo "  * <${HOSTNAME}-$$> {"$(my_date)"} All task is executed";
	rm ${FILE_CPU};
    fi;
}

#-----[ Corps ]---------------------------------------------
execute ${*};
