## @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>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

SetWorkspace() {

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

  #
  # Set $WORKSPACE
  #
  WORKSPACE=$(pwd)
  export WORKSPACE

  return 0

}

RestorePreviousConfiguration() {
  #
  # Restore previous configuration
  #
  if [ -z "$CONF_PATH" ]
  then
    export CONF_PATH=$WORKSPACE/Conf
    if [ ! -d $WORKSPACE/Conf ] && [ -n "$PACKAGES_PATH" ]
    then
      for DIR in $(echo $PACKAGES_PATH | tr ':' ' ')
      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 "  FOUND_TOOLS_PATH_BIN=0"                             >> $OUTPUT_FILE
  echo "  for DIR in \$(echo \$PATH | tr ':' ' '); do"        >> $OUTPUT_FILE
  echo "    if [ \"\$DIR\" = \"$EDK_TOOLS_PATH_BIN\" ]; then" >> $OUTPUT_FILE
  echo "      FOUND_TOOLS_PATH_BIN=1"                         >> $OUTPUT_FILE
  echo "    fi"                                               >> $OUTPUT_FILE
  echo "  done"                                               >> $OUTPUT_FILE
  echo "  if [ \$FOUND_TOOLS_PATH_BIN = 0 ]"                  >> $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 BaseTools/BuildEnv" >| $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
    for DIR in $(echo $PACKAGES_PATH | tr ':' ' ')
    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
  #
  echo $(uname -sm | tr ' ' '-')
}

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:$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

