#
# Copyright (c) 2006 - 2007, Intel Corporation. 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.

#
# Setup the environment for unix-like systems running a bash-like shell.
# This file must be "sourced" not merely executed. For example: ". edksetup.sh"
#

SetWorkspace() {

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

  if [ ! ${BASH_SOURCE[0]} -ef ./BaseTools/BuildEnv ]
  then
    echo Run this script from the base of your tree.  For example:
    echo "  cd /Path/To/Edk/Root"
    echo "  . BaseTools/BuildEnv"
    return 1
  fi

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

  return 0

}

RestorePreviousConfiguration() {
  #
  # Restore previous configuration
  #
  PREVIOUS_CONF_FILE=Conf/BuildEnv.sh
  if [ -e $PREVIOUS_CONF_FILE ]
  then
    echo Loading previous configuration from \$WORKSPACE/$PREVIOUS_CONF_FILE
    . $WORKSPACE/$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/BuildEnv.sh
  #echo Storing current configuration into \$WORKSPACE/$OUTPUT_FILE
  OUTPUT_FILE=$WORKSPACE/$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 $WORKSPACE/Conf/EdkTools
  #
  if [ -e $WORKSPACE/Conf/EdkTools ]
  then
    export EDK_TOOLS_PATH=$WORKSPACE/Conf/EdkTools
    return 0
  fi

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

  #
  # Try $WORKSPACE/BaseTools
  #
  if [ -e $WORKSPACE/BaseTools ]
  then
    export EDK_TOOLS_PATH=$WORKSPACE/BaseTools
    return 0
  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
}

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`

  if [ ! -e $EDK_TOOLS_PATH_BIN ]
  then
    echo "Unable to find expected bin path under \$EDK_TOOLS_PATH!"
    echo "> $EDK_TOOLS_PATH_BIN"
    return 1
  fi

  if [ "${PATH/$EDK_TOOLS_PATH_BIN/}" == "$PATH" ]
  then
    export PATH=$EDK_TOOLS_PATH_BIN:$PATH
    return 0
  fi

}

CopySingleTemplateFile() {

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

  if [ -e $WORKSPACE/$DST_FILENAME ]
  then
    return
  fi

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

}

CopyTemplateFiles() {

  CopySingleTemplateFile build_rule
  CopySingleTemplateFile FrameworkDatabase
  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

  CopyTemplateFiles

}

#
# Run the main function
#
ScriptMain

