#!/usr/bin/env bash
set -e

function aggregate_start() {
  echo "👉 Aggregation Starts into ${1}"
  echo "massRegister(" >>"${1}"
}


function aggregate_end() {
  echo "👉 Aggregation Ends into ${1}"
  echo "0,0);" >>"${1}"
}

# mithril app builder
# (c) rodolfo lp 2019
# network required for closure compiler

function aggregate() {

  echo "👉 Aggregating folder ${1} recursively"
  # Create Aggregated Libraries
  for filename in ${1}/**/*.js; do

    if [[ -f ${filename} ]]; then

      FILEFOLDER="$(
        cd "$(dirname "$filename")" >/dev/null 2>&1
        pwd -P
      )"

      PARENTFOLDER=$(basename "$FILEFOLDER")

      fname=$(basename "$filename")
      fname="${fname%.*}"

      if [[ "${fname}" == "main" && ${PARENTFOLDER} == "src" ]]; then
        echo "- main is handled separately"
      else
        echo "- Adding module ${fname} from ${PARENTFOLDER}"

        echo "M${i}, (exports, require, module) => {" >>"${2}"

        # echo "requireRegister(M${i}, (exports, require, module) => {" >>"${2}"
        cat "${filename}" >>"${2}"

        echo >>"${2}"
        echo "}," >>"${2}"
      fi
      i=$((i + 1))

    else
      echo "- No third party libraries found in ${PROJLIB}."
    fi
  done
}

function aggregateStyle() {

  FILESTRING=$(eval echo "${1}/*.css")
  FILES=($FILESTRING)

  echo "👉 Aggregating styles in $1"

  for filename in "${FILES[@]}"; do
    if [[ -f $filename ]]; then
      fname=$(basename "$filename")
      fname="${fname%.*}"
      echo "- including ${BUILDTYPE} ${NAME} style [${fname}]"
      cat "${filename}" >>"${BUILDDIR}/${BUILDTYPE}.css"
    fi
  done
}

function obfuscateModules() {

  echo "👉 Obfuscating modules in ${1}"

  for filename in ${1}/**/*.js; do

    if [[ -f ${filename} ]]; then

      FILEFOLDER="$(
        cd "$(dirname "$filename")" >/dev/null 2>&1
        pwd -P
      )"
      PARENTFOLDER=$(basename "$FILEFOLDER")

      fname=$(basename "$filename")
      fname="${fname%.*}"

      if [[ "$2" -eq "1" ]]; then
        fname="${PARENTFOLDER}.${fname}"
      fi

      md5=$(echo -n ${fname} | md5sum - | cut -b 1-32)

      echo "- parsing ${fname} ... index ${i} ... md5 ${md5}"

      asig="${asig}M${i},"
      valu=${valu}\"${fname}\",
      valumd5=${valumd5}\"${md5}\",

      # require("mitril") => require(M34)
      buscar="require(\"${fname}\")"
      cambiar="require(M${i})"

      # echo "= buscar ${buscar} cambiar ${cambiar}"

      #     sed -i "" -e "s/${buscar}/${cambiar}/g" "${BUILDDIR}/${BUILDTYPE}.rx.js"
      sed -i -e "s/${buscar}/${cambiar}/g" "${BUILDDIR}/${BUILDTYPE}.rx.js"

      i=$((i + 1))
    fi
  done
}

if [[ ! -d "${TEMPDEST}" ]]; then
  echo "! Init script not executed."
  exit 6
fi

if [[ -z "${BUILDDIR}" ]]; then
  echo "! Init script not executed."
  exit 7
fi

# For using recursive directory search(requires bash v4+)
shopt -s globstar

PROJROOT=${SOURCEROOT}/${NAME}
PROJSRC=${PROJROOT}/src
PROJLIB=${PROJROOT}/lib
PROJEXTRA=${PROJROOT}/extra

echo "- PROJSRC IS ${PROJSRC}"
[[ -d ${PROJSRC} ]] || {
  echo "! No source files found in ${PROJSRC}"
  exit 200
}

if [[ -z "${TEMPLATE}" ]]; then
  TEMPLATE=default
fi

TEMPLATEROOT=${TOOLROOT}/templates
CURRENTTEMPLATE="${TEMPLATEROOT}/${BUILDTYPE}/${TEMPLATE}"

echo "- Using Template ${TEMPLATE}"

#####
TARGFILE="${BUILDDIR}/${BUILDTYPE}.js"
CONTFILE=$TARGFILE

echo "-----------------"
echo "Phase 1/4: Aggregate and create ${BUILDTYPE}${BUILDFLAV} Closure"
cp "${TOOLROOT}/build/make-src/${BUILDTYPE}${BUILDFLAV}-closure.in.jst" "${TARGFILE}" || exit 100

#if [[ -n $BUILDENC ]]; then
#  CONTFILE="${BUILDDIR}/${BUILDTYPE}.enc.js"
#  touch $CONTFILE
#fi

cat "${TOOLROOT}/build/make-src/template${BUILDFLAV}.js" >>"${CONTFILE}" || exit 100

if [[ -f ${PROJSRC}/main.js.in ]]; then
  echo "- Using custom In closure"
  cat "${PROJSRC}/main.js.in" >>"${CONTFILE}"
else
  echo "- No custom In closure in ${PROJSRC}/main.js.in"
fi

i="0"

aggregate_start "${CONTFILE}"
aggregate "${CURRENTTEMPLATE}/src" "${CONTFILE}"
aggregate "${PROJLIB}" "${CONTFILE}"
aggregate "${PROJSRC}" "${CONTFILE}"
aggregate_end "${CONTFILE}"

if [[ -f ${PROJSRC}/main.js ]]; then
  echo "- Using Custom Application Entry Point"
  MAINFILE=${PROJSRC}/main.js
elif [[ -f ${CURRENTTEMPLATE}/src/main.js ]]; then
  echo "- Using Template Application Entry Point"
  MAINFILE=${CURRENTTEMPLATE}/src/main.js
else
  echo "! No Entry Point, please create main.js in ${PROJSRC} if needed"
fi

if [[ -n "${MAINFILE}" ]]; then
  cat "${MAINFILE}" >>"${CONTFILE}"
fi

if [[ -f ${PROJSRC}/main.js.out ]]; then
  echo "- Using custom out closure"
  cat "${PROJSRC}/main.js.out" >>"${CONTFILE}"
else
  echo "- No custom out closure in ${PROJSRC}/main.js.out"
fi

#if [[ -n $BUILDENC ]]; then
#  RESULT=$(${TOOLROOT}/build/make-src/encodebase.js ${CONTFILE})
#  echo "//////////////////////// ${CONTFILE} " >>"${TARGFILE}"
#  echo "eval (atob(\"${RESULT}\"));" >>"${TARGFILE}"
#  echo "/////" >>"${TARGFILE}"
#fi

cat "${TOOLROOT}/build/make-src/${BUILDTYPE}${BUILDFLAV}-closure.out.jst" >>"${TARGFILE}"

cp "${BUILDDIR}/${BUILDTYPE}.js" "${BUILDDIR}/${BUILDTYPE}.rx.js"

if [[ ! -f "${BUILDDIR}/${BUILDTYPE}.rx.js" ]]; then
  echo "! failed to create ${BUILDDIR}/${BUILDTYPE}.rx.js"
  exit 99
fi

echo "-----------------"
echo "Phase 2/4: Obfuscate module names"

i="0"
asig=""
valu=""
valumd5=""

if [[ -d "${CURRENTTEMPLATE}/src" ]]; then
  obfuscateModules "${CURRENTTEMPLATE}/src"
fi

if [[ -d "${PROJLIB}" ]]; then
  obfuscateModules "${PROJLIB}"
fi

if [[ -d "${PROJSRC}" ]]; then
  obfuscateModules "${PROJSRC}"
fi

echo "${BUILDOUTVAR}(function (${asig}XX) {" >"${BUILDDIR}/${BUILDTYPE}.ox.js"
cat "${BUILDDIR}/${BUILDTYPE}.rx.js" >>"${BUILDDIR}/${BUILDTYPE}.ox.js"
echo "})(${valumd5}0)" >>"${BUILDDIR}/${BUILDTYPE}.ox.js"

# need to turn off uselessCode as it complains when re-minifying mithril.js
npx google-closure-compiler ${CCMODE} --jscomp_off uselessCode --jscomp_off suspiciousCode --js="${BUILDDIR}/${BUILDTYPE}.ox.js" --js_output_file="${BUILDDIR}/${BUILDTYPE}.min.js"

if [[ -f ${PROJEXTRA}/libs.txt ]]; then
  "${TOOLROOT}/scripts/crunch.sh" "${PROJEXTRA}/libs.txt" ${TEMPDEST}/${BUILDTYPE}.js
else
  touch ${TEMPDEST}/${BUILDTYPE}.js
fi

if [[ -n "${BUILD_DEBUG}" ]]; then
  cp "${TEMPDEST}/${BUILDTYPE}.js" "${TEMPDEST}/${BUILDTYPE}.debug.js"
  cat "${BUILDDIR}/${BUILDTYPE}.ox.js" >> "${TEMPDEST}/${BUILDTYPE}.debug.js"
fi

cat "${BUILDDIR}/${BUILDTYPE}.min.js" >>"${TEMPDEST}/${BUILDTYPE}.js"

echo "-----------------"
echo "Phase 3/4: Compile  ${BUILDTYPE} ${NAME} Styles"

# copy extra styles

if [[ -f ${PROJEXTRA}/css.txt ]]; then
  "${TOOLROOT}/scripts/crunch.sh" "${PROJEXTRA}/css.txt" "${BUILDDIR}/${BUILDTYPE}.css"
fi

# copy template styles

aggregateStyle "${CURRENTTEMPLATE}/css/**"

# copy main module styles
aggregateStyle "${PROJROOT}/css"
aggregateStyle "${PROJROOT}/css/**"

# copy section styles
aggregateStyle "${PROJSRC}/**/css"

# cp "${BUILDDIR}/${BUILDTYPE}.css"  "${TEMPDEST}/${BUILDTYPE}.css"

if [[ -f "${BUILDDIR}/${BUILDTYPE}.css" ]]; then

  if [[ -n ${BUILD_SKIPMINIFYCSS} ]]; then
    echo "! Not Minifying styles"
    cp "${BUILDDIR}/${BUILDTYPE}.css" "${TEMPDEST}/${BUILDTYPE}.css"
  else
    echo "- Minifying styles"
    echo "${NODEMODULES}/.bin/uglifycss" "${BUILDDIR}/${BUILDTYPE}.css"
    "${NODEMODULES}/.bin/uglifycss" "${BUILDDIR}/${BUILDTYPE}.css" >"${TEMPDEST}/${BUILDTYPE}.css"
  fi

fi

echo "-----------------"
echo "Phase 4/4: Copying ${BUILDTYPE} ${NAME} Assets"

if [[ -d "${CURRENTTEMPLATE}/assets" ]]; then
  cp -r ${CURRENTTEMPLATE}/assets/* "${TEMPDEST}/" || echo "- Template ${TEMPLATE} does not provide Assets" && echo "- Including ${TEMPLATE} assets"
else
  echo "- ${TEMPLATE} does not provide Assets"
fi

if [[ -d "${PROJROOT}/assets" ]]; then
  cp -r ${PROJROOT}/assets/* "${TEMPDEST}/" 2>/dev/null || echo "- ${BUILDTYPE} ${NAME} does not provide additional assets"
else
  echo "- ${BUILDTYPE} ${NAME} does not provide additional assets"
fi

echo "-----------------"
echo "${BUILDTYPE} ${NAME}: Build Finished."
echo "✅  Generated files in ${TEMPDEST}"

if [[ -d ${BUILDDIR} && -z ${KEEP} ]]; then
  rm -rf "${BUILDDIR}"
fi
