## @file
# Setup the environment for unix-like systems running a bash-like shell.
# This file must be "sourced" not merely executed. For example: ". edksetup.sh"
#
# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# 
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

SetWorkspace() {

  #
  # If WORKSPACE is already set, then we can return right now
  #
  if [ -n "$WORKSPACE" ]
  then
    return 0
  fi

  #
  # Set $WORKSPACE
  #
  export WORKSPACE=`pwd`

  return 0

}

RestorePreviousConfiguration() {
  #
  # Restore previous configuration
  #
  if [ -z "$CONF_PATH" ]
  then
    export CONF_PATH=$WORKSPACE/Conf
    if [ ! -d $WORKSPACE/Conf ] && [ -n "$PACKAGES_PATH" ]
    then
      PATH_LIST=${PACKAGES_PATH//:/ }
      for DIR in $PATH_LIST
      do
        if [ -d $DIR/Conf ]
        then
          export CONF_PATH=$DIR/Conf
          break
        fi
      done
    fi
  fi
  
  PREVIOUS_CONF_FILE=$CONF_PATH/BuildEnv.sh
  if [ -e $PREVIOUS_CONF_FILE ]
  then
    echo Loading previous configuration from $PREVIOUS_CONF_FILE
    . $PREVIOUS_CONF_FILE
  fi
}

GenerateShellCodeToSetVariable() {
  VARIABLE=$1
  OUTPUT_FILE=$2
  VAR_VALUE="echo \${${VARIABLE}}"
  VAR_VALUE=`eval $VAR_VALUE`
  echo "if [ -z \"\$${VARIABLE}\" ]"             >> $OUTPUT_FILE
  echo "then"                                    >> $OUTPUT_FILE
  echo "  export ${VARIABLE}=${VAR_VALUE}"       >> $OUTPUT_FILE
  echo "fi"                                      >> $OUTPUT_FILE
}

GenerateShellCodeToUpdatePath() {
  OUTPUT_FILE=$1
  echo "if [ -e $EDK_TOOLS_PATH_BIN ]"                        >> $OUTPUT_FILE
  echo "then"                                                 >> $OUTPUT_FILE
  echo "  if [ "\${PATH/$EDK_TOOLS_PATH_BIN/}" == "\$PATH" ]" >> $OUTPUT_FILE
  echo "  then"                                               >> $OUTPUT_FILE
  echo "    export PATH=$EDK_TOOLS_PATH_BIN:\$PATH"           >> $OUTPUT_FILE
  echo "  fi"                                                 >> $OUTPUT_FILE
  echo "fi"                                                   >> $OUTPUT_FILE
}

StoreCurrentConfiguration() {
  #
  # Write configuration to a shell script to allow for configuration to be
  # easily reloaded.
  #
  OUTPUT_FILE=$CONF_PATH/BuildEnv.sh
  #echo Storing current configuration into $OUTPUT_FILE
  echo "# Auto-generated by ${BASH_SOURCE[0]}" > $OUTPUT_FILE
  GenerateShellCodeToSetVariable WORKSPACE $OUTPUT_FILE
  GenerateShellCodeToSetVariable EDK_TOOLS_PATH $OUTPUT_FILE
  GenerateShellCodeToUpdatePath $OUTPUT_FILE
}

SetEdkToolsPath() {

  #
  # If EDK_TOOLS_PATH is already set, then we can return right now
  #
  if [ -n "$EDK_TOOLS_PATH" ]
  then
    return 0
  fi

  #
  # Try $CONF_PATH/EdkTools
  #
  if [ -e $CONF_PATH/EdkTools ]
  then
    export EDK_TOOLS_PATH=$CONF_PATH/EdkTools
    return 0
  fi

  #
  # Try $CONF_PATH/BaseToolsSource
  #
  if [ -e $CONF_PATH/BaseToolsSource ]
  then
    export EDK_TOOLS_PATH=$CONF_PATH/BaseToolsSource
    return 0
  fi

  #
  # Try $WORKSPACE/BaseTools
  #
  if [ -e $WORKSPACE/BaseTools ]
  then
    export EDK_TOOLS_PATH=$WORKSPACE/BaseTools
    return 0
  fi

  #
  # Try $PACKAGES_PATH
  #
  if [ -n "$PACKAGES_PATH"]
  then
    PATH_LIST=${PACKAGES_PATH//:/ }
    for DIR in $PATH_LIST
    do
      if [ -d $DIR/BaseTools ]
      then
        export EDK_TOOLS_PATH=$DIR/BaseTools
        return 0
      fi
    done
  fi

  echo "Unable to determine EDK_TOOLS_PATH"
  echo
  echo "You may need to download the 'BaseTools' from buildtools.tianocore.org."
  echo "After downloading, either create a symbolic link to the source at"
  echo "\$WORKSPACE/Conf/BaseToolsSource, or set the EDK_TOOLS_PATH environment"
  echo "variable."

}

GetBaseToolsBinSubDir() {
  #
  # Figure out a uniq directory name from the uname command
  #
  UNAME_DIRNAME=`uname -sm`
  UNAME_DIRNAME=${UNAME_DIRNAME// /-}
  UNAME_DIRNAME=${UNAME_DIRNAME//\//-}
  echo $UNAME_DIRNAME
}

GetEdkToolsPathBinDirectory() {
  #
  # Figure out a uniq directory name from the uname command
  #
  BIN_SUB_DIR=`GetBaseToolsBinSubDir`

  if [ -e $EDK_TOOLS_PATH/BinWrappers/$BIN_SUB_DIR ]
  then
    EDK_TOOLS_PATH_BIN=$EDK_TOOLS_PATH/BinWrappers/$BIN_SUB_DIR
  else
    EDK_TOOLS_PATH_BIN=$EDK_TOOLS_PATH/Bin/$BIN_SUB_DIR
  fi

  echo $EDK_TOOLS_PATH_BIN
}

AddDirToStartOfPath() {
  DIRNAME=$1
  PATH=$DIRNAME:$DIRNAME:$DIRNAME:$PATH
  PATH=${PATH//$DIRNAME:/}
  PATH=$DIRNAME:$PATH
  export PATH
}

AddEdkToolsToPath() {

  #
  # If EDK_TOOLS_PATH is not set, then we cannot update PATH
  #
  if [ -z "$EDK_TOOLS_PATH" ]
  then
    return 1
  fi

  EDK_TOOLS_PATH_BIN=`GetEdkToolsPathBinDirectory`

  AddDirToStartOfPath $EDK_TOOLS_PATH/BinWrappers/PosixLike
  AddDirToStartOfPath $EDK_TOOLS_PATH_BIN

}

CopySingleTemplateFile() {

  SRC_FILENAME=Conf/$1.template
  DST_FILENAME=$CONF_PATH/$1.txt

  if [ -e $DST_FILENAME ]
  then
    [ $RECONFIG != TRUE ] && return
  fi

  echo "Copying \$EDK_TOOLS_PATH/$SRC_FILENAME"
  echo "     to $DST_FILENAME"
  SRC_FILENAME=$EDK_TOOLS_PATH/$SRC_FILENAME
  cp $SRC_FILENAME $DST_FILENAME

}

CopyTemplateFiles() {

  CopySingleTemplateFile build_rule
  CopySingleTemplateFile tools_def
  CopySingleTemplateFile target

}

ScriptMain() {

  SetWorkspace
  if [ -z $WORKSPACE ]
  then
    echo "Failure setting WORKSPACE"
    return 1
  fi

  RestorePreviousConfiguration

  SetEdkToolsPath
  if [ -z $EDK_TOOLS_PATH ]
  then
    return 1
  fi

  AddEdkToolsToPath
  if [ $? -ne 0 ]
  then
    echo "Failure adding EDK Tools into PATH!"
    return 1
  fi

  StoreCurrentConfiguration

  echo WORKSPACE: $WORKSPACE
  echo EDK_TOOLS_PATH: $EDK_TOOLS_PATH
  echo CONF_PATH: $CONF_PATH

  CopyTemplateFiles

}

#
# Run the main function
#
ScriptMain