#!/bin/bash

set -e -o pipefail

. ${SCRIPTS:-/}start-utils
if isDebugging; then
  set -x
fi

#  CURSE_URL_BASE used in manifest downloads below
CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}

# Remove old mods/plugins
if isTrue ${REMOVE_OLD_MODS:-false}; then
  removeOldMods /data/mods
  removeOldMods /data/plugins
fi

# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
if [[ "$MODPACK" ]]; then
  if isURL "${MODPACK}"; then
    if [[ "${MODPACK}" == *.zip ]]; then
      downloadUrl="${MODPACK}"
    else
      downloadUrl=$(curl -Ls -o /dev/null -w %{effective_url} $MODPACK)
      if ! [[ $downloadUrl == *.zip ]]; then
        log "ERROR Invalid URL given for MODPACK: $downloadUrl resolved from $MODPACK"
        log "      Must be HTTP, HTTPS or FTP and a ZIP file"
        exit 1
      fi
    fi

    log "Downloading mod/plugin pack"
    log "  from $downloadUrl ..."
    if ! curl -sSL -o /tmp/modpack.zip "$downloadUrl"; then
      log "ERROR: failed to download from $downloadUrl"
      exit 2
    fi
  elif [[ "$MODPACK" =~ .*\.zip ]]; then
    if ! cp $MODPACK /tmp/modpack.zip; then
      log "ERROR: failed to copy from $MODPACK"
      exit 2
    fi
  else
    log "ERROR Invalid URL or Path given for MODPACK: $MODPACK"
    exit 1
  fi

  if [ "$TYPE" = "SPIGOT" ]; then
    mkdir -p /data/plugins
    if ! unzip -o -d /data/plugins /tmp/modpack.zip; then
      log "ERROR: failed to unzip the modpack from $downloadUrl"
    fi
  else
    mkdir -p /data/mods
    if ! unzip -o -d /data/mods /tmp/modpack.zip; then
      log "ERROR: failed to unzip the modpack from $downloadUrl"
    fi
  fi
  rm -f /tmp/modpack.zip
fi

# If supplied with a URL for a plugin download it.
if [[ "$MODS" ]]; then
  if [ "$TYPE" = "SPIGOT" ]; then
    out_dir=/data/plugins
  else
    out_dir=/data/mods
  fi
  mkdir -p "$out_dir"

  for i in ${MODS//,/ }
  do
    if isURL $i; then
      log "Downloading mod/plugin $i ..."
      if isValidFileURL jar "$i"; then
        if ! curl -fsSL -o "${out_dir}/$(getFilenameFromUrl "${i}")" "${i}"; then
          log "ERROR: failed to download from $i into $out_dir"
          exit 2
        fi
      else
        effective_url=$(resolveEffectiveUrl "$i")
        if isValidFileURL jar "${effective_url}"; then
          out_file=$(getFilenameFromUrl "${effective_url}")
          if ! curl -fsSL -o "${out_dir}/$out_file" "${effective_url}"; then
            log "ERROR: failed to download from $i into $out_dir"
            exit 2
          fi
        else
          log "ERROR: $effective_url resolved from $i is not a valid jar URL"
          exit 2
        fi
      fi
    elif [[ -f "$i" && "$i" =~ .*\.jar ]]; then
      log "Copying plugin located at $i ..."
      out_file=$(basename "$i")
      if ! cp "$i" "${out_dir}/$out_file"; then
        log "ERROR: failed to copy from $i into $out_dir"
        exit 2
      fi
    elif [[ -d "$i" ]]; then
      log "Copying plugin jars from $i ..."
      cp "$i"/*.jar "${out_dir}"
    else
      log "ERROR Invalid URL or path given in MODS: $i"
      exit 2
    fi
  done
fi

if [[ "$MANIFEST" ]]; then
    if [[ -e "$MANIFEST" ]]; then
        EFFECTIVE_MANIFEST_FILE=$MANIFEST
    elif isURL "$MANIFEST"; then
        EFFECTIVE_MANIFEST_FILE=/tmp/manifest.json
        EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w %{effective_url} $MANIFEST)
        curl -Ls -o $EFFECTIVE_MANIFEST_FILE "$EFFECTIVE_MANIFEST_URL"
    else
        log "MANIFEST='$MANIFEST' is not a valid manifest url or location"
        exit 2
    fi

case "X$EFFECTIVE_MANIFEST_FILE" in
  X*.json)
    if [ -f "${EFFECTIVE_MANIFEST_FILE}" ]; then
      MOD_DIR=${FTB_BASE_DIR:-/data}/mods
      if [ ! -d "$MOD_DIR" ]
      then
        log "Creating mods dir $MOD_DIR"
        mkdir -p "$MOD_DIR"
      fi
      log "Starting manifest download..."
      cat "${EFFECTIVE_MANIFEST_FILE}" | jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)'| while read -r p f
      do
        if [ ! -f $MOD_DIR/${p}_${f}.jar ]
        then
          redirect_url="$(curl -Ls -o /dev/null -w %{effective_url} ${CURSE_URL_BASE}/${p})"
          url="$redirect_url/download/${f}/file"
          log Downloading curseforge mod $url
          #  Manifest usually doesn't have mod names. Using id should be fine, tho
          curl -sSL "${url}" -o $MOD_DIR/${p}_${f}.jar
        fi
      done
    else
      log "Could not find manifest file, unsufficient privs, or malformed path."
    fi
    ;;
  *)
    log "Invalid manifest file for modpack. Please make sure it is a .json file."
    ;;
esac
fi

if [[ "${GENERIC_PACK}" ]]; then
  if isURL "${GENERIC_PACK}"; then
    log "Downloading generic pack ..."
    curl -fsSL -o /tmp/generic_pack.zip "${GENERIC_PACK}"
    GENERIC_PACK=/tmp/generic_pack.zip
  fi

  sum_file=/data/.generic_pack.sum
  if ! sha256sum -c ${sum_file} -s 2> /dev/null; then
    base_dir=/tmp/generic_pack_base
    mkdir -p ${base_dir}
    isDebugging && ls -l "${GENERIC_PACK}"
    unzip -q -d ${base_dir} "${GENERIC_PACK}"
    if [ -f /data/manifest.txt ]; then
      log "Manifest exists from older generic pack, cleaning up ..."
      while read f; do
        rm -rf "/data/${f}"
      done < /data/manifest.txt
      find /data/* -type d -exec rmdir --ignore-fail-on-non-empty {} +
      rm -f /data/manifest.txt
    fi
    log "Writing generic pack manifest ... "
    find ${base_dir} -type f -print0 | xargs -0 -I {} echo "{}" | sed "s#${base_dir}/##" > /data/manifest.txt
    log "Applying generic pack ..."
    IFS='
'
    set -f
    for d in $(find ${base_dir} -type d); do mkdir -p "$(sed "s#${base_dir}#/data#" <<< $d)"; done
    for f in $(find ${base_dir} -type f); do cp -f "$f" "$(sed "s#${base_dir}#/data#" <<< $f)"; done
    rm -rf ${base_dir}
    sha256sum "${GENERIC_PACK}" > ${sum_file}
  fi
fi

exec ${SCRIPTS:-/}start-finalSetupModconfig $@
