#!/bin/bash
# Skel - generate skeletal Stroika-based C++ application (point is setting up default makefiles etc)
#
#   Parameters:
#       --appRoot <DIR>     # top level directory generated
#       --stroika-source (git | download)
#
POSITIONAL_ARGS=()
APP_ROOT=""
TEMPLATE="Basic"
APP_NAME=""
STROIKA_SOURCE="git"
STROIKA_SOURCE_GIT_REMOTE="https://github.com/SophistSolutions/Stroika.git"
STROIKA_SOURCE_GIT_STROIKA_BRANCH=`git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'v3-Release'`

get_script_dir_ () {
     #https://www.ostricher.com/2014/10/the-right-way-to-get-the-directory-of-a-bash-script/
     SOURCE="${BASH_SOURCE[0]}"
     # While $SOURCE is a symlink, resolve it
     while [ -h "$SOURCE" ]; do
          DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
          SOURCE="$( readlink "$SOURCE" )"
          # If $SOURCE was a relative symlink (so no "/" as prefix, need to resolve it relative to the symlink base directory
          [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
     done
     DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
     echo "$DIR"
}
MY_PATH_=$(get_script_dir_)
StroikaRoot=${MY_PATH_}/../

help_()
{
  echo "Skel";
  echo "  --appRoot <DIR>         # top level directory generated (required - e.g. ../myApp)"
  echo "  [--template T ]         # defaults to Basic, but supported: [Basic, HTMLUI]"
  echo '  [--appName <NAME>]      # top level directory generated (DEFAULT: `basename \$\{APP_ROOT\}` no spaces in name, and no punct except _)'
  echo "  [--stroikaSource git]"
  # todo add | download | symbolic-link, or maybe conan, but NYI --LGP 2023-10-24
}
parse_command_line_ () {
  while [[ $# -gt 0 ]]; do
    case $1 in
      --appRoot)
        APP_ROOT="$2"
        shift # past argument
        shift # past value
        ;;
      --appName)
        APP_NAME="$2"
        shift # past argument
        shift # past value
        ;;
      --template)
        TEMPLATE="$2"
        shift # past argument
        shift # past value
        if [[ ! -e "$MY_PATH_/Shared/Skel-Templates/$TEMPLATE/Extras.sh" ]] ; then
          echo "Unknown template $TEMPLATE"
          help_;
          exit 1
        fi
        ;;
      --stroikaSource)
        echo "NYI - only support git for now... $1"
        ;;
      -h|--help)
        help_;
        exit 0
        ;;
      -*|--*)
        echo "Unknown option $1"
        help_;
        exit 1
        ;;
      *)
        POSITIONAL_ARGS+=("$1") # save positional arg
        shift # past argument
        ;;
    esac
  done

  if [[ "$APP_ROOT" == "" ]] ; then
    help_;
    exit 1
  fi
  if [[ "$APP_NAME" == "" ]] ; then
    APP_NAME=`basename ${APP_ROOT}`
  fi
}

mkTopLevelDir_()
{
    echo "Making top level directory: $APP_ROOT"
    mkdir -p $APP_ROOT
}
mkThirdPartyComponentsAndStroika_()
{
    echo "Making $APP_ROOT/ThirdPartyComponents/Stroika"
    mkdir -p $APP_ROOT/ThirdPartyComponents/Stroika
    cp $MY_PATH_/Shared/Skel-Templates/Common/ThirdPartyComponents/Makefile $APP_ROOT/ThirdPartyComponents/
    cp $MY_PATH_/Shared/Skel-Templates/Common/ThirdPartyComponents/Stroika/Makefile $APP_ROOT/ThirdPartyComponents/Stroika/
    if [[ "$STROIKA_SOURCE" == "git" ]] ; then
      echo "Initializing git repository and adding Stroika submodule"
      (cd $APP_ROOT && git init)
      (cd $APP_ROOT/ThirdPartyComponents/Stroika; git submodule add $STROIKA_SOURCE_GIT_REMOTE StroikaRoot)
      (cd $APP_ROOT/ThirdPartyComponents/Stroika/StroikaRoot; git checkout ${STROIKA_SOURCE_GIT_STROIKA_BRANCH})
    fi
}
mkMyApp_()
{
  echo "Making $APP_ROOT/{Workspaces, .vscode} etc..."
  mkdir -p  \
    $APP_ROOT/Workspaces/VisualStudio.Net \
    $APP_ROOT/Workspaces/VSCode \
    $APP_ROOT/.vscode

  mkdir -p $APP_ROOT/Workspaces/VSCode
  sed s/\$\{APP_NAME\}/${APP_NAME}/g < $MY_PATH_/Shared/Skel-Templates/Common/Workspaces/VSCode/MyApp.code-workspace > $APP_ROOT/Workspaces/VSCode/$APP_NAME.code-workspace

  cp $MY_PATH_/Shared/Skel-Templates/Common/VERSION $APP_ROOT/
  cp $MY_PATH_/Shared/Skel-Templates/Common/ReadMe.md $APP_ROOT/
  cp $StroikaRoot/.gitignore $APP_ROOT

  (export MY_PATH_ APP_ROOT APP_NAME TEMPLATE && $MY_PATH_/Shared/Skel-Templates/$TEMPLATE/Extras.sh)
}
mkFinish_()
{
  echo "Genericly adjusting $APP_ROOT contents for skel produced app..."
  (cd $APP_ROOT/Workspaces/VisualStudio.Net; $StroikaRoot/ScriptsLib/MakeSymbolicLink ../../ThirdPartyComponents/Stroika/StroikaRoot/Workspaces/VisualStudio.Net/Microsoft.Cpp.stroika.ConfigurationBased.props)
  (cd $APP_ROOT/Workspaces/VisualStudio.Net; $StroikaRoot/ScriptsLib/MakeSymbolicLink ../../ThirdPartyComponents/Stroika/StroikaRoot/Workspaces/VisualStudio.Net/Microsoft.Cpp.stroika.user.props)
  (cd $APP_ROOT; $StroikaRoot/ScriptsLib/MakeSymbolicLink ThirdPartyComponents/Stroika/StroikaRoot/.clang-format)
  
  sed s/\$\{APP_NAME\}/${APP_NAME}/g < $MY_PATH_/Shared/Skel-Templates/Common/.vscode/launch.json > $APP_ROOT/.vscode/launch.json
  sed s/\$\{APP_NAME\}/${APP_NAME}/g < $MY_PATH_/Shared/Skel-Templates/Common/.vscode/settings.json > $APP_ROOT/.vscode/settings.json
  sed s/\$\{APP_NAME\}/${APP_NAME}/g < $MY_PATH_/Shared/Skel-Templates/Common/.vscode/tasks.json > $APP_ROOT/.vscode/tasks.json
  cp $MY_PATH_/Shared/Skel-Templates/Common/.vscode/.gitignore $APP_ROOT/.vscode/
  cp $StroikaRoot.config-default.json $APP_ROOT/.config.json
}





parse_command_line_ $*;

OUTLOG=$APP_ROOT/"Skel-Output-$APP_NAME.txt"

echo "Building skeletal app:"
echo "  directory: $APP_ROOT"
echo "  app name:  $APP_NAME"
echo "  template:  $TEMPLATE"
echo "  log:       $OUTLOG"

if [[ -e $APP_ROOT ]] ; then
  echo "FAILED: Delete appRoot ($APP_ROOT) so not accidentally clobbered"
  exit 1
fi
mkdir -p $APP_ROOT
mkTopLevelDir_ >> $OUTLOG 2>&1
mkThirdPartyComponentsAndStroika_ >> $OUTLOG 2>&1
mkMyApp_ >> $OUTLOG 2>&1
mkFinish_ >> $OUTLOG 2>&1

echo "  done"
echo "Suggested next step:"
echo "  cd $APP_ROOT; make CONFIGURATION=Debug all -j8"
