#!/bin/bash
#------------------------------------------------------------------------------
#
# \brief    obtains stm hal libraries from github
#
#           receives stm hal libraries and copies
#           necccessary files for libshw used by libbiwak.
#
# \author   Maximilian Seesslen <development@seesslen.net>
#
#------------------------------------------------------------------------------


set -e
set -u


OPWD="$PWD"
ORGPWD="$PWD"
INCPATH="../include/stm"
SRCPATH="../src"
DOCPATH="./doc"
MCU_REV="f4"
base_url="https://github.com/STMicroelectronics"

# -t: retries; -T: timeout for everything (read, connect, ...)
# 5 retries where to less for large images on bad infrastructure
WGETFLAGS="-t15 -T15"
# TEMP=$(mktemp -d)

DATA="${DATA:=}"
if [ -z "${DATA}" ]; then
   # When building in containers, DATA might not be set but /data is mounted.
   if [ -e "/data/$USER" ]; then
      DATA="/data/$USER"
      TEMP="$DATA/obj/libHALWrapper"
   else
      TEMP="$HOME/obj/libHALWrapper"
   fi
else
    TEMP="$DATA/obj/libHALWrapper"
fi

mkdir -p $TEMP

[ -z "$TEMP" ] && ( echo "could not get temp directory '$TEMP'"; exit 22 )
[ ! -d "$TEMP" ] && ( echo "could not get temp directory '$TEMP'"; exit 22 )
if [ "$(dirname $TEMP)" != "/tmp" ] && [ "$(dirname $TEMP)" != "$HOME/obj" ] \
   && [ "$(dirname $TEMP)" != "$DATA/obj" ]; then
	echo "Unplasible temp name: $TEMP"
	exit 22
fi


ARCHIVE_PATH="${ARCHIVE_PATH:=}"
if [ -z "${ARCHIVE_PATH}" ]; then
	ARCHIVE_PATH="${TEMP}"
fi

SOURCE_PATH="${SOURCE_PATH:=}"
if [ -z "${SOURCE_PATH}" ]; then
   SOURCE_PATH="${ARCHIVE_PATH}"
fi

# Use any Project for families
PROJECT_F0="STM32F072RB-Nucleo"
REVISION_F0=v1.11.5
PROJECT_F1="STM32F103RB-Nucleo"
REVISION_F1=v1.8.6
PROJECT_F3="STM32F334R8-Nucleo"
REVISION_F3=v1.11.5
PROJECT_F4="STM32F4-Discovery"
REVISION_F4=v1.27.1

PROJECT_L0="NUCLEO-L011K4"
REVISION_L0=v1.12.2
PROJECT_L1="STM32L152D-EVAL"
REVISION_L1=v1.10.4
PROJECT_L4="STM32L476G-EVAL"
REVISION_L4=v1.18.1

PROJECT_G0="NUCLEO-G071RB"
REVISION_G0=v1.6.2
PROJECT_G4="NUCLEO-G491RE"
REVISION_G4=v1.6.1

# Sample URL for tags: https://github.com/STMicroelectronics/STM32CubeF1/tags

init()
{
   cd "$OPWD"

   INCPATH="./include/${MCU_REV}/stm"
   SRCPATH="./src/${MCU_REV}"

   mkdir -p ${ARCHIVE_PATH} && cd ${ARCHIVE_PATH}
}


### \brief  This will indirectly download an archive from ST server
###
###         Problem is that ST controls downloading via Login etc. This function
###         works around some limitations.
###
###         First it downloads the corresponding html page, parse the actual URL,
###         make some magic and download the actual file.
receiveFile()
{
   echo -e "\n\n\n"
   echo "### MCU: $MCU_REV"
   mainUrl="$1"
   zipFile="$2"
   shift
   echo "### Base Url: $mainUrl"

   mainFile="${zipFile}"
   [ -e "${mainFile}.done" ] || rm -f "$mainFile"
   [ -e "${mainFile}" ] && echo "   ### '${mainFile}' already exists in $PWD"
   [ -e "${mainFile}" ] || wget $WGETFLAGS "${mainUrl}" -O ${zipFile}|| echo "Could not download"

   echo "Base downloaded"

   fileName="${zipFile}"
   if [ "$(file $fileName --mime-type)" != "$fileName: application/zip" ]; then
      echo "Error: this file if not a zip."
      file $fileName --mime-type
      exit 22
    fi

    touch "${fileName}.done"
    echo "   ### done."
}

shovelFiles()
{
   cd $OPWD
	rm -rf $INCPATH $SRCPATH $DOCPATH/HAL $DOCPATH/CMSIS
	mkdir -p $SRCPATH $INCPATH $DOCPATH/HAL $DOCPATH/CMSIS

	chmod 755 $SRCPATH $INCPATH $DOCPATH/HAL $DOCPATH/CMSIS

	echo "### Target Pathes: $PWD; -> $SRCPATH $INCPATH $DOCPATH/HAL $DOCPATH/CMSIS"

   cp ${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/Src/*.c $SRCPATH
   cp ${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/Inc/*.h $INCPATH
	cp ${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/Release_Notes.html $DOCPATH/HAL
	if [ -d "${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/_htmresc" ]; then
		cp -r ${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/_htmresc $DOCPATH/HAL
	else
		cp -r ${sourcePath}/_htmresc $DOCPATH/HAL
	fi
   
   if [ -e "${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/LICENSE.md" ]; then
      cp -r ${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/LICENSE.md $DOCPATH/HAL
   else
      cp -r ${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/License.md $DOCPATH/HAL/LICENSE.md
   fi
   
	if [ -e "${sourcePath}/License.md" ]; then
	    cp ${sourcePath}/License.md $DOCPATH/LICENSE.md
	else
	    cp ${sourcePath}/LICENSE.md $DOCPATH
	fi
	if [ -e "${sourcePath}/Drivers/CMSIS/LICENSE.txt" ]; then
		cp ${sourcePath}/Drivers/CMSIS/LICENSE.txt $DOCPATH/CMSIS
	else
		cp ${sourcePath}/Drivers/CMSIS/Lib/license.txt $DOCPATH/CMSIS
	fi

	if [ -e "${sourcePath}/Drivers/CMSIS/README.md" ]; then
		cp ${sourcePath}/Drivers/CMSIS/README.md $DOCPATH/CMSIS
	else
		cp ${sourcePath}/README.md $DOCPATH/CMSIS
	fi

   if [ -d "${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/Inc/Legacy" ]; then
      cp -R ${sourcePath}/Drivers/STM32${MCU_REV^^}xx_HAL_Driver/Inc/Legacy $INCPATH
   fi

   if [ -d "${sourcePath}/Drivers/CMSIS/Device/ST/STM32${MCU_REV^^}xx/Include" ]; then
      cp ${sourcePath}/Drivers/CMSIS/Device/ST/STM32${MCU_REV^^}xx/Include/*.h $INCPATH
   fi
   if [ -d "${sourcePath}/Drivers/CMSIS/Include" ]; then
      cp ${sourcePath}/Drivers/CMSIS/Include/*.h $INCPATH
   fi

   BOARD_NAME="BOARD_${MCU_REV^^}"
   PROJECT_NAME="PROJECT_${MCU_REV^^}"
   # cp ${sourcePath}/Projects/${!PROJECT_NAME}/Templates/Inc/stm32${MCU_REV}xx_hal_conf.h $INCPATH
   cp $INCPATH/stm32${MCU_REV}xx_hal_conf_template.h $INCPATH/stm32${MCU_REV}xx_hal_conf.h

      cp ${sourcePath}/Drivers/CMSIS/Device/ST/STM32${MCU_REV^^}xx/Source/Templates/gcc/startup_stm32*.s \
               $SRCPATH
      cp ${sourcePath}/Drivers/CMSIS/Device/ST/STM32${MCU_REV^^}xx/Source/Templates/system_stm32${MCU_REV}xx.c \
                        $SRCPATH
}


# Creates GIT repository and applies patches
gitInitPart()
{
   gitSourcePath="$1"
   gitPatchPath="$2"

   mkdir -p  "${gitPatchPath}"
   cd "$OPWD"
   cd "$gitSourcePath"
    if [ ! -d ".git" ]; then
       git init > /dev/null
       git add * > /dev/null
       git commit -m "initial commit"
       git checkout -b my
    else
	echo "git repository already set up."

    fi

   if [ ! -e ".patched" ]; then
      echo "Checking for local patches"
      for pfile in $(ls ${gitPatchPath}); do
          echo "Applying $pfile"
          git am --keep-cr < ${gitPatchPath}/$pfile
      done
      touch ".patched"
   fi
   cd "$OPWD"
}


gitInit()
{
   gitInitPart "$SRCPATH" "$OPWD/patches/${MCU_REV}/src"
   gitInitPart "$INCPATH" "$OPWD/patches/${MCU_REV}/include"
}


extractArchive()
{
   extractArchiveOpwd="$PWD"

   rm -rf "${SOURCE_PATH}/stm32${MCU_REV}"
   mkdir -p "${SOURCE_PATH}/stm32${MCU_REV}"
   cd "${SOURCE_PATH}/stm32${MCU_REV}"
   rm -rf *
   echo "   ### Im on $PWD"
   unzip "${ARCHIVE_PATH}/$fileName" > /dev/null

   sourcePath="${SOURCE_PATH}/stm32${MCU_REV}/$(ls)"

   cd "$extractArchiveOpwd"
}


receiveRepo()
{
   repo=$1
   bn=$(basename $repo)
   subpath=stm32${MCU_REV}/$bn
   # -${!PROJECT_REVISION}
   mkdir -p $(dirname $subpath)
   [ -e "$subpath" ] || git clone $repo $subpath
   pushd $subpath
   git checkout ${!PROJECT_REVISION}
   # git submodule init
   # git submodule update
   git submodule update --init --recursive
   popd
   sourcePath="${SOURCE_PATH}/${subpath}"
}


receive()
{
   optional=no
   cd $TEMP
   PROJECT_REVISION="REVISION_${MCU_REV^^}"

   #receiveFile "${base_url}/STM32Cube${MCU_REV^^}/archive/refs/tags/${!PROJECT_REVISION}.zip" \
   #      "stm32cube${MCU_REV}.zip"
   #extractArchive

   receiveRepo "${base_url}/STM32Cube${MCU_REV^^}"
}


all()
{
   (
      flock -x 200

      init
      receive
      shovelFiles

      gitInit
   ) 200>${ARCHIVE_PATH}/${MCU_REV}.lock
}


show()
{
   init
   echo "URL: ${base_url}/patch_cubefw_${MCU_REV}.zip"
}


if [ "$#" -gt "0" ]; then
    MCU_REVS="$@"
else
    MCU_REVS="f0 f1 f3 f4 l1 l4 g0 g4"
fi

for MCU_REV in $MCU_REVS; do
    all
done

if [ "$TEMP" != "/tmp/libshw" ]; then
   # rm -rf $TEMP
   echo -n
fi

echo "[$0] fin."


#---fin------------------------------------------------------------------------
