#!/bin/bash

#
# File .......... swuk_create_vitis_project
# Author ........ Steve Haywood
# Website ....... http://www.spacewire.co.uk
# Project ....... Common (SpaceWire UK Tutorial)
# Date .......... 25 Jun 2025
# Version ....... 2.0
# History .......
#   1.0 common/sw/src/script/create_vitis_project.sh
# Description ...
#   Very simple script to launch the Xilinx software command-line tool,
# run the TCL script and launch Vitis. Should be run in the project host
# directory that contains the fw & sw subdirectories, for example :-
#
# user@host:~/swuk_tutorial/project$ swuk_create_vitis_project
# user@host:~/swuk_tutorial/project$ swuk_create_vitis_project --build
#

# Strict
#set -euo pipefail


################################################################################
# Main function.
# Arguments ...... ${@}
# Return ......... None
# Exit code ...... Status (0=success, 1=failure)
# Shared (In) .... None
# Shared (Out) ... None
main()
{
  # Declare argument constants
  local -r  c_optbuild="--build"  # Str: Build option name
  local -r  c_opthelp="--help"    # Str: Help option name
  local -Ar c_options=(           # ARR: Options & associated help information
    [${c_optbuild}]="Build the project after creation."
    [${c_opthelp}]="Display this help and exit."
  )
  local -ar c_optorder=(          # Arr: Help options display order
    ${c_optbuild}
    ${c_opthelp}
  )
  local -ar argv=(${@})           # Arr: Get argument values (space-separated) into array

  # Declare argument variables
  local     arg                   # Str: Current argument from argv array
  local     option                # Str: Current option from c_optorder array

  # Display help information
  if [[ " ${argv[*]} " =~ " ${c_opthelp} " ]]; then
    echo "Usage: $(basename ${0}) [OPTION]..."
    echo "Create a new Vitis project using the $(basename ${0}).tcl script & optionally build it."
    echo
    for option in ${c_optorder[@]}
    do
      echo "      ${option} $(printf ' %.0s' {1..12} | head -c $((12-${#option}))) ${c_options[${option}]}"
    done
    echo
    exit 0
  fi

  # Get & check the arguments
  for arg in ${argv[@]}; do
    if [[ ${arg:0:2} == "--" ]]; then  # Option
      [[ ! -v c_options[${arg}] ]] &&
        echo "Option (${arg}) is not recognised!" >&2 &&
        exit 1
    else
      echo "Unexpected argument (${arg}) found!" >&2
      exit 1
    fi
  done

  # Declare operational constants & variables
  local -r c_dir_script=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
                                       # Str: Script location directory
  local -r c_dir_pwd=$(pwd)            # Str: Current working directory (full path)
  local -r c_project=${c_dir_pwd##*/}  # Str: Last element of pwd (project name)
  local -r c_dir_base="sw"             # Str: Software base directory
  local -r c_dir_project="vitis"       # Str: Vitis project directory
  local    tclargs=""                  # Str: Arguments sent to TCL script

  # Sanity check directory structure
  [ ! -d ${c_dir_base} ] &&
    echo "Software base directory ${c_dir_base} does not exists!" >&2 &&
    exit 1

  [ -d ${c_dir_base}/${c_dir_project} ] &&
    echo "Vitis project directory ${c_dir_base}/${c_dir_project} already exists!" >&2 &&
    exit 1

  # Create & move into the new project directory
  mkdir -p ${c_dir_base}/${c_dir_project}
  cd ${c_dir_base}/${c_dir_project}

  # Check for build argument
  [[ " ${argv[*]} " =~ " ${c_optbuild} " ]] && tclargs="build"

  # Call Xilinx Software Commandline Tool
  xsct "${c_dir_script}/$(basename ${0}).tcl" "${c_project}" ${tclargs}

  # Launch Vitis
  vitis -workspace . &

  # Move back out of project directory
  cd ../..
}


################################################################################
# Opening gambit.
# Arguments ...... ${@}
# Return ......... None
# Exit code ...... Status (0=success, 1=failure)
# Shared (In) .... None
# Shared (Out) ... None
main ${@}
exit 0
