#!/bin/bash
#set defaults
if [ -z "$EAMDdirectoryName" ]; then
	EAMDdirectoryName="EAMD.ucp"
	debug.log "EAMDdirectoryName: $EAMDdirectoryName"
fi

if [ -z "$EAMDdirectory" ]; then
	EAMDdirectory="/$EAMDdirectoryName/"
	debug.log "EAMDdirectory: $EAMDdirectory"
fi

if [ -z "$defaultWorkspace" ]; then
    defaultWorkspace=$(cd .;pwd)
	debug.log "defaultWorkspace: $defaultWorkspace"
fi

if [ -z "$componentDir" ]; then
	componentDir="Components"
	debug.log "componentDir: $componentDir"
fi

if [ -z "$scenarioDir" ]; then
	scenarioDir="Scenarios"
	debug.log "scenarioDir: $scenarioDir"
fi

if [ -z "$defaultVersion" ]; then
	defaultVersion="0.0.0-GIT-Repository"
	debug.log "defaultVersion: $defaultVersion"
fi

if [ -z "$defaultServer" ]; then
	defaultServer="http://structr.cerulean.it:6082"
	debug.log "defaultServer: $defaultServer"
fi

if [ -z "$defaultUser" ]; then
	defaultUser="guest"
	debug.log "defaultUser: $defaultUser"
fi

if [ -z "$mochaTemplateDir" ]; then
    mochaTemplateDir="${EAMDdirectory}Components/tla/EAMD/MochaTemplates"
    debug.log "mochaTemplateDir: $mochaTemplateDir"
fi

if [ -z "$mochaTemplateVerison" ]; then
    mochaTemplateVerison="1.0.0"
    debug.log "mochaTemplateVerison: $mochaTemplateVerison"
fi

#done set defaults


create() {
    shift
    debug.log " function create($*)"
    while [ -n "$1" ]; do
        let i++
        debug.log "Parameter($i): $1"

        case $1 in
            component)
                debug.log "...create component" 
                createComponent $2 $3 $4
                exit 0
                ;;
            weBean)
                debug.log "create WeBean"
                createWeBean $2 $3 $4
                exit 0
                ;;
            version)
                debug.log "create version"
                createVersion $2 $3 $4
                exit 0
                ;;
            descriptor)
                debug.log "create descriptor"
                createDescriptor $2 $3 $4
                exit 0
                ;;

             test)
                debug.log "create test"
                createTest $2 $3 $4
                exit 0
                ;;
             mochaTest)
                debug.log "create mocha test"
                createMochaTest $2 $3
                exit 0
               ;;
            *)
                err.log "don\'t know $1"
                console.log "You can create: component | descriptor | weBean | version | mochaTest"

                ;;
       esac

        shift
    done
    echo "You can create:"
    echo "      component some.component.Name 0.1.0"
    echo "      version   some.component.Name 0.2.0"
    echo "      weBean    . <?version> <?weBeanName=Name>"
    echo "      test some.namespace.component 0.1.0"
    echo "      mochaTest some.namespace.component 0.1.0"
}

createComponent() {
    component=$1
    version=$2

    if [ -z "$version" ]; then
        version=$defaultVersion
    fi

    createComponentNamescpaces $component $version

    #createDir $componentPath/$componentName
    #createDir $componentPath/$componentName/$version

    createFile $componentPath/$componentName.component.xml

    tree $componentPath
}

createComponentNamescpaces() {
    component=$1
    version=$2
    debug.log " function createComponentNamescpaces(component: $component, version: $version)"

    init
    namespace2ComponentPath $component $version
    componentPath=$path
    createPath $componentPath

}

createVersion() {
    component=$1
    newVersion=$2
    oldVersion=$3
    verion=$newVersion
    debug.log " function createVersion(component $component, newVersion: $newVersion, oldVersion $oldVersion)"
 
    findComponent $component $oldVersion
    oldVersion=$version

    debug.log " function createVersion(component $component, newVersion: $newVersion, oldVersion $oldVersion)"

    current=$componentPath

    debug.log "componentName $componentname, componentPath: $componentPath, current $current)"

    if [ ! -d $current ]; then
        err.log "$current does not exists"
        exit -1
    fi
    current=$componentPath/../$newVersion
    if [ ! -d $current ]; then
    debug.log "componentName $componentname, componentPath: $componentPath, current $current)"
        cp -R $componentPath $current
        console.log "$current:"
        ls -al $current
    else
        err.log "$current aready exists"
        exit -1
    fi

}


createWeBean() {
    component=$1
    if [ -z "$component" ]; then
        component="."
    fi
    version=$2
    weBeanName=$3
    debug.log " function createWeBean(component $component, weBeanName: $weBeanName)"
    if [ -z "$version" ]; then
        version=$defaultVersion
    fi

    #createComponentNamescpaces $component
    #findComponent $component $version
    getComponentDetails $component $version

    if [ -z "$weBeanName" ]; then
        weBeanName=$componentName
    fi
    debug.log "Path: $componentPath   Name: $componentName     weBeanName: $weBeanName"

    createPath $componentRootPath/$version/src/html/weBeans
    createFile $componentRootPath/$version/src/html/weBeans/$weBeanName.weBean.html

    createPath $componentRootPath/$version/src/js
    createFile $componentRootPath/$version/src/js/$weBeanName.class.js
 
    tree $componentRootPath$version/src

}

createDescriptor() {
    current=$1
    if [ -z "$current" ]; then
        current=.
    fi

    debug.log " function createDescriptor(path $current)"

    createFile $current/Default.component.xml
    update
}


init() {
    debug.log " function init($1 $2 $3)"
    if [ -d $defaultWorkspace ]; then
        workspace=""
        for current in ${defaultWorkspace//// }; do 
            debug.log "checking namespace: $current"
            debug.log "checking path: $workspace/$current"
            workspace=$workspace/$current

            if [ "$current" = "$EAMDdirectoryName" ]; then
                break
            fi
        done
        debug.log "$EAMDdirectoryName Workspace = $workspace"
    else
        err.log "current Workspace does not exist: $defaultWorkspace"
        exit -1
    fi


    if [ ! -d $EAMDdirectory ]; then
        err.log "$EAMDdirectoryName Directory does not exist: $EAMDdirectory"
        if [ ! -L $EAMDdirectory ]; then
            err.log "current Link does not exist: $EAMDdirectory"
            console.log "create link $EAMDdirectory --> $workspace"
            createPath $EAMDdirectory
            ln -sf  $workspace/$componentDir $EAMDdirectory$componentDir
        else
            console.log "EAMD.ucp exists and is a link"
        fi
    else
        console.log "$EAMDdirectoryName Directory exists: $EAMDdirectory"
    fi
}

createPath() {
    debug.log " function createPath($1)"

  
    if [[ "$1" = /* ]]; then
        cd "/"
    fi

    path=""
    debug.log "creating path in $(pwd)"

    for current in ${1//// }; do 

        if [ -z "$path" ]; then
            path=$current
        else
            path=$path/$current
        fi
        debug.log "checking path: $path"

        createDir $path
    done
}


createDir() {
    current=$1
    if [ ! -d $current ]; then
        debug.log "$current does not exist: creating it..."   
        mkdir -p $current
    fi
}

createFile() {
    current=$1
    if [ ! -w $current ]; then
        debug.log "$current does not exist: creating it..."   
        touch $current
    fi
}

update() {
    debug.log " function update($1 $2 $3)"
    component=$1

    if [ -z "$component" ]; then
        component=.
    fi
   
    #findComponent $component $2 $3
    getComponentDetails $component

    echo "** componentRootPath: $componentRootPath"

    if [ -w "$componentRootPath/Default.component.xml" ]; then
        console.log found
        mv $componentRootPath/Default.component.xml $componentPath/$component.component.xml
    fi

    componentName=$component
 #   createWeBean $component $version

    downloadUnit . $componentName.component.xml
    downloadUnit . src/html/weBeans/$componentName.weBean.html
    downloadUnit . src/js/$componentName.class.js

    #exit 0;

}

namespace2ComponentPath() {
    component=$1
    version=$2
    debug.log " function createComponentNamescpaces(component: $component, version: $version)"

    if [ "${component////}" = "$component" ] ; then
        if [ "$component" = "." ]; then
            debug.log "is path ."
            path=.
        else
            debug.log "is namespcae"
            namespace2path $component
            componentName=$lastItem

            path=$EAMDdirectory$componentDir$path$version
        fi
    else
        debug.log "is path $component"
        path=$component
    fi

    debug.log "looking for Component: $componentName in $path"
}

findComponent() {
    debug.log " function findComponent($1 $2 $3)"
    component=$1
    version=$2
    if [ -z "$version" ]; then
        version=$defaultVersion
    fi
   filePattern="*.component.xml"

    namespace2ComponentPath $component $version
    componentPath=$path

    current=$path
    dir=$path

    while [ "$dir" != "$EAMDdirectoryName" ] && [ "$dir" != "/" ]; do
        debug.log "$dir  --> $current"

        if [ -d "$current" ] ; then
            current=$(cd $current; pwd)
        else
            echo "$current is not a directory"
            break;
        fi

        dir=$(basename $current)
        debug.log "$dir  --> $current:    $current/$filePattern"
        
        if ls $current/$filePattern 1> /dev/null 2>&1; then
            break
        else
            debug.log "files do not exist"
        fi
        current=$current/..
    done

    if [ "$dir" == "$EAMDdirectoryName" ] || [ "$dir" == "/" ]; then
        err.log "No component found. Please enter a Version directory of an existing component"
        exit -1
    fi

    componentPath=$current
    console.log "Found Component in: $componentPath"
    version=$(basename $componentPath)
}


getComponentDetails() {
    current=$1
    if [ -z "$current" ]; then
        current="."
    fi
    debug.log " function getComponentDetails(componentPath $current $2 $3)"
    findComponent $current $2
    #current=$1

    filepath=$current/../..
    component=${filepath%/*}
    component=$(cd $component; pwd)
    component=$(basename $component)
    debug.log "Component: $component    Path:$componentPath"

    filepath=$current/..
    version=${filepath%/*}
    version=$(cd $version; pwd)
    version=$(basename $version)
    debug.log "Version: $version"

    workspace=""
    workspaceFound=false
    namespace=""
    for current in ${componentPath//// }; do 
        debug.log "checking namespace: $current"
        debug.log "checking path: $workspace/$current"


        if $workspaceFound ; then
            if [ "$current" = "Components" ]; then
                namespace=""
            else
                if [ "$namespace" = "" ]; then
                    namespace=$current
                else
                    namespace=$namespace.$current
                fi
            fi
        else
            workspace=$workspace/$current
        fi

        if [ "$current" = "$EAMDdirectoryName" ]; then
            workspaceFound=true
        fi

        if [ "$current" = "$component" ]; then
            break
        fi
    done

    componentAbsolutePath=$componentPath
    namespace2path $namespace
    componentPath=$path
    componentRootPath=$EAMDdirectory$componentDir$componentPath
    componentName=$component

    console.log "Component Path.....: componentAbsolutePath = $componentAbsolutePath"
    console.log "$EAMDdirectoryName  Workspace: workspace = $workspace"
    console.log "Component Root Path: componentRootPath = $componentRootPath"
    console.log "Component Namespace: namespace = $namespace"
    console.log "Component Name.....: component = $component"
    console.log "Component Version..: version = $version"
    console.log "Component Descriptor         = $componentRootPath$version/$componentName.component.xml"
    
    
}


namespace2path() {
    namespace=$1
    debug.log " function namespace2path(namespace $namespace)"
    convertList $namespace "/" "." "/" "/"
    path=$result
}

path2namespace() {
    path=$1
    debug.log " function path2namespace(namespace $path)"
    convertList $path "." "/"
    namespcae=$result
}


convertList() {
    list=$1
    next=$2
    seperator=$3
    first=$4
    last=$5
    debug.log " function convertList(first $first, next: $next, last: $last, seperator: $seperator, list: $list)"

    result=$first
    for current in ${list//$seperator/ }; do 
            if [ "$result" = "$first" ]; then
                result=$result$current
            else
                result=$result$next$current
            fi
        debug.log "$result"
    done
    result=$result$last
    lastItem=$current
    console.log "$result"
}


findVersions() {
    component=$1
    getComponentDetails $component $2

    debug.log " function findVersions(component $component)"
    cd $componentAbsolutePath/..
    result=$( basename [0-9]* )
    console.log "all Versions:"
    versions=$result

    convertList "$versions" ", " "\ " #"[ " " ]"
    latestVersion=$lastItem
    console.log "latest Version: $latestVersion"    
}

downloadComponentDescriptor() {
    component=$1
    if [ "$component" = "." ]; then
        #findComponent $component
        getComponentDetails $componentPath
    fi
    debug.log " function downloadComponentDescriptor(component $component)"

    downloadFile $componentRootPath$version/$component.component.xml $componentAbsolutePath/$component.component.xml
}

downloadUnit() {
    component=$1
    unit=$2
    if [ "$component" = "." ]; then
        #findComponent $component
        getComponentDetails $component $2
    fi
    debug.log " function downloadComponentDescriptor(component $component)"

    downloadFile $componentRootPath$version/$unit $componentAbsolutePath/$unit
}

downloadFile() {
    remoteFile=$1
    localFile=$2
    debug.log " function donloadFile(remoteFile $remoteFile, localFile $localFile)"
    console.log "downloading $defaultServer$remoteFile"
    console.log "         to $localFile"
    curl -o $localFile $defaultServer$remoteFile
}


createDevEnvironment() {
    devPath=$1
    if [ -z "$devPath" ]; then
        devPath=/var/
    fi
    debug.log " function createDevEnvironment(devPath $devPath)"

    createPath $devPath/dev/Server
    createPath $devPath/dev/IDE
    createPath $devPath/dev/GIT-Repositories
    createPath $devPath/dev/Workspaces
    createPath $devPath/dev/Workspaces/UCP
    createPath $devPath/dev/Workspaces/eclipse
    createPath $devPath/dev/Workspaces/structr
}

setupUser() {
    userPath=$1
    if [ -z "$userPath" ]; then
        userPath="~/"
    fi
    
    createPath $userPath/scripts
    ln -s $0 $userPath/scripts
    echo PATH=$PATH:$userPath/scripts
}

lookupDescriptor() {
    name=$1
    debug.log " function lookupDescriptor(devPath $name)"

    curl http://structr.cerulean.it:6082/structr/rest/UcpComponentDescriptor?name=$name.component.xml | tr -d '\n' |   grep -o '"[A-Za-z_][A-Za-z_0-9]\+"\s*:\s*\("[^"]\+"\|[0-9\.]\+\|true\|false\|null\)' |   sed 's/"\(.*\)"\s*:\s*"\?\([^"]\+\)"\?/\1="\2"/' 

    if [ -z "$path" ]; then
        err.log "$name not found"
    else
        console.log "Descriptor File: $path"
    fi


}

createTest() {
    component=$1
    if [ -z "$component" ]; then
        component="."
    fi
    version=$2
    weBeanName=$3
    debug.log " function createTest(component $component, version $version, weBeanName: $weBeanName)"
    if [ -z "$version" ]; then
        version=$defaultVersion
    fi

    #createComponentNamescpaces $component
    #findComponent $component $version
    getComponentDetails $component $version

    if [ -z "$weBeanName" ]; then
        weBeanName=$componentName
    fi
    debug.log "Path: $componentPath   Name: $componentName     weBeanName: $weBeanName"
    
    # check if the component and version are ok, only then create the test file

    if ls $componentAbsolutePath 1> /dev/null 2>&1; then   
        createPath $componentRootPath/$version/test/html/
        createFile $componentRootPath/$version/test/html/${weBeanName}Test.html
		tree $componentRootPath$version/test
    else
        echo "Either component or version is wrong! Enter the component with namespace eg. com.twitter.Bootstrap.Button"
    fi
}

createMochaTest(){
    component=$1
    if [ -z "$component" ]; then
        component="."
    fi
    version=$2

    if [ -z "$version" ]; then
        version=$defaultVersion
    fi
    echo "createMochaTest $component $version"
    getComponentDetails $component $version

    src="$mochaTemplateDir/$mochaTemplateVerison/js/default.js"

    dstDir="$componentAbsolutePath/test/js"
    dst="$dstDir/${component}.mochaTest.js"
    descriptor="$componentRootPath$version/$componentName.component.xml"

    createDir $dstDir
    cat $src |sed s/%ComponentName%/$component/ | sed s/%ComponentVersion%/$version/ | awk "{ gsub(/%ComponentDescriptor%/, \"$descriptor\"); print }" > $dst

}

createTestFileForAllComponents() {

    findAllLocalComponents 
   
    ctr=0
    oddEven=0
    npath=${p//@/ }
    
    for i in $npath
    do 
        #echo $i
        let ctr++
        oddEven=`expr $ctr % 2`

        if [ $oddEven -eq 1 ]; then
            component=$i
        fi

        if [ $oddEven -eq 0 ]; then
            version=$i
            if [ ! "$version" == "null" ]; then
                component=${component//"/"/"."}
                component=${component/".EAMD.ucp.Components."}
                component=${component/%".$version".*/}
                console.log "can call createtest with parameters $component and $version"
                createTest $component $version
            fi
        fi
    done
    #echo $lst
}

findAllStructrUcpComponents() {
    name=$1
    debug.log " function findAllStructrUcpComponents(devPath $name)"

    
   path=$(curl -s http://structr.cerulean.it:6082/structr/rest/UcpComponentDescriptor/ui| jq '.result[]| "\(.path) \(.version | "\(.name)")"')
   path=${path//.component.xml/@}
   path=${path//\"/}
   ctr=0
    #echo $path
    for i in $path
    do
        #echo $i
         v=`expr $ctr % 2`

        if [ $ctr -eq 0 ]; then
        #echo "in first call"
            p=$i
        else
            #echo $ctr
            if [ $v -eq 0 ]; then
            #echo "calling the path2namespace"
                #path2namespace $i
               
                #namespcae=${namespcae/"/"/"."}
                namespcae=${namespcae/"/EAMD.ucp/Components/"/}
                # echo "result of eamd replacement $namespcae"
                #namespcae=${namespcae/$version.*/}
                p+=$namespcae
            #echo "result of namespace $namespcae"
            else
                p+=$i            
            fi
        fi
       
        if [ $v -gt 0 ]; then            
           #p="$p
             #"        
			p+=$'\n'
        fi
      
        let ctr++

    done
   

    if [ -z "$path" ]; then
        err.log "$name not found"
    else
        echo "$p"
    fi


}

findAllLocalComponents() {
    
    dWorkspace=$defaultWorkspace
    debug.log " function findAllLocalComponents()"    
    debug.log " find /$EAMDdirectoryName/$componentDir -name *.component.xml"    
    list=`find "/$EAMDdirectoryName/$componentDir" -name "*.component.xml"`
    # -exec createTest {} \;
    
    for i in $list
    do
               
                namespcae=${i/"$/$EAMDdirectoryName/$componentDir/"/}
                                
                component=`echo $namespcae | rev | cut -d'/' -f-1 | rev`
               
                namespcae=${namespcae/$component/}
                component=${component/".component.xml"}
              
                version=`echo $namespcae | rev | cut -d'/' -f-2 | rev`
                version=${version/'/'}
                
                namespcae=${namespcae/$version}
                namespcae=${namespcae/"//"}
                namespcae=${namespcae//"/"/.}
                
                p+=$namespcae@$version
       
			p+=$'\n'       
    done
   

    if [ -z "$p" ]; then
        err.log "$p not found"
    else
        echo "$p"
    fi

    
}

if [ -z "$1" ]; then
    script=$(basename $0)
	echo "usage: $0 command parameter
        commands are
            init:  creates the /$EAMDdirectoryName link 
            create:
                $script create component some.component.Name 0.1.0        
                $script create version   some.component.Name 0.2.0        
                $script create version   . 0.2.0        
                $script create weBean    . <?version> <?weBeanName=Name>
                $script create test      some.namespace.component 0.1.0
                $script create mochaTest some.namespace.component 0.1.0
            update:
            list: <?componentFullQualifiedName=.> <?version> <?weBeanName=Name>
            test:
                $script test someFunction some parameters
                $script test namespace2path some.namespace
                $script test path2namespcae /some/path
                $script test findVersions .
"
    exit -1
fi

i=0

while [ -n "$1" ]; do
    let i++
    debug.log "Parameter($i): $1"

    case $1 in
        create)
            debug.log "...create..."
            create $*
            ;;
        init)
            debug.log "...init..."
            init $*
            ;;
        update)
            debug.log "update component"
            update
            ;;
        list)
            debug.log "list"
            getComponentDetails .
            ;;
        test)
            debug.log "$*"
            shift
            $*
            #exit 0
            ;;
        *)
            debug.log "dont know $1"
            ;;
    esac
    
    case $i in
        1)
            debug.log "setting var1 to $1"
            var1=$1
            ;;
        2)
            debug.log "setting var2 to $1"
            var2=$1
            ;;
        3)
            debug.log "setting var3 to $1"
            var3=$1
            ;;
    esac


    shift
done

#exit 0
