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

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

  #
  # 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/Bin/$UNAME_DIRNAME
  #
  if [ -e $WORKSPACE/BaseTools/Bin/$UNAME_DIRNAME ]
  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=BaseTools/Conf/$1.template
  DST_FILENAME=Conf/$1.txt

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

  echo "Copying \$WORKSPACE/$SRC_FILENAME"
  echo "     to \$WORKSPACE/$DST_FILENAME"
  SRC_FILENAME=$WORKSPACE/$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

