#! /bin/bash
(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required

# --------------------------------------------------------------------
set -e

# --------------------------------------------------------------------
: ${OVERSION=4.02.1}
: ${EC_TOOLCHAIN_ROOT="${PWD}/_tools"}       # MUST BE ABSOLUTE
: ${EC_JOBS=1}

# --------------------------------------------------------------------
PATCHES=ocaml-patches.diff
OBREW_URL=https://www.easycrypt.info/toolchain/ocamlbrew

OPAM_VERSION=1.2.0
OPAM_URL=https://github.com/ocaml/opam/releases/download/${OPAM_VERSION}/opam-full-${OPAM_VERSION}.tar.gz
ECOPAM_URL=git://github.com/EasyCrypt/opam.git

OCONFIG_BASE="ocaml-${OVERSION}/etc/ocamlbrew.bashrc"
OCONFIG="${EC_TOOLCHAIN_ROOT}/${OCONFIG_BASE}"

export OCAMLBREW_BASE=${EC_TOOLCHAIN_ROOT}
export OCAMLBREW_FLAGS="-v ${OVERSION} -f"
# export OCAMLBREW_FLAGS="-v ${OVERSION} -p ${PWD}/scripts/patches/${PATCHES} -f"
export OCAMLBREW_JOBS=${EC_JOBS}
export OPAMJOBS=${EC_JOBS}

export OPAMROOT=${EC_TOOLCHAIN_ROOT}/ocaml-${OVERSION}/opam
export OPAMFLAGS="--no-setup"

unset OCAMLFIND_CONF
unset OCAML_TOPLEVEL_PATH
unset CAML_LD_LIBRARY_PATH

case $(uname -s) in
  CYGWIN*)
    buildtype=cygwin;;
  *)
    buildtype=posix;;
esac


# --------------------------------------------------------------------
if [ "${EC_TOOLCHAIN_ROOT}" != "${EC_TOOLCHAIN_ROOT//[ ]/}" ]; then
  echo "Destination folder contains spaces" >&2
  echo "Please, set the EC_TOOLCHAIN_ROOT variable to a valid value" >&2
  exit 1
fi

# --------------------------------------------------------------------
function check_cmd {
  if ! type -P "$1" >/dev/null 2>&1; then
    echo "missing program: $1. install it first" >&2
    exit 1
  fi
}

check_cmd m4
check_cmd autoconf
check_cmd gcc
check_cmd g++
check_cmd curl

if [ ${buildtype} = "cygwin" ]; then
  check_cmd ocaml
fi

# --------------------------------------------------------------------
if [ -e "${EC_TOOLCHAIN_ROOT}" ]; then
  echo "Remove ${EC_TOOLCHAIN_ROOT} first." >&2
  exit 1
fi

set -e

mkdir "${EC_TOOLCHAIN_ROOT}" "${EC_TOOLCHAIN_ROOT}/src"

if [ ${buildtype} != "cygwin" ]; then
  curl -f -kL -o "${EC_TOOLCHAIN_ROOT}/src/ocamlbrew" ${OBREW_URL}
  bash "${EC_TOOLCHAIN_ROOT}/src/ocamlbrew" ${OCAMLBREW_FLAGS}
else
  mkdir "${EC_TOOLCHAIN_ROOT}"/ocaml-${OVERSION}/
  mkdir "${EC_TOOLCHAIN_ROOT}"/ocaml-${OVERSION}/build
  mkdir "${EC_TOOLCHAIN_ROOT}"/ocaml-${OVERSION}/etc
  cat >>"${OCONFIG}" <<-EOF
export PATH="${EC_TOOLCHAIN_ROOT}/ocaml-${OVERSION}/bin:\${PATH}"
EOF
fi

# --------------------------------------------------------------------
function build_opam {
    source "${OCONFIG}"

    curl -f -kL -O ${OPAM_URL}
    rm -rf opam-full-${OPAM_VERSION}
    tar -xozf opam-full-${OPAM_VERSION}.tar.gz

    cd opam-full-${OPAM_VERSION}
    ./configure --prefix="${EC_TOOLCHAIN_ROOT}/ocaml-${OVERSION}"
    make lib-ext && make && make install

    "${EC_TOOLCHAIN_ROOT}"/ocaml-${OVERSION}/bin/opam init ${OPAMFLAGS}
    "${EC_TOOLCHAIN_ROOT}"/ocaml-${OVERSION}/bin/opam repository add ec ${ECOPAM_URL}

    cat >>"${OCONFIG}" <<-EOF
export PS1="(ec-tool) \${PS1}"
export OCAMLFIND_CONF="${EC_TOOLCHAIN_ROOT}/ocaml-${OVERSION}/opam/system/lib/findlib.conf"
export OPAMROOT="${OPAMROOT}"
. ${OPAMROOT}/opam-init/variables.sh
EOF
}

( set -e; cd "${EC_TOOLCHAIN_ROOT}"/ocaml-${OVERSION}/build && build_opam )

source "${OCONFIG}"

opam install -v -y ec-toolchain

# --------------------------------------------------------------------
set +xe

function box {
    echo
    echo "$@" |sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$p' -e '$x'
    echo
}

box "EasyCrypt toolchain installed"

cat <<EOF
%%% --------------------------------------------------------------------
%%%
%%% To use it, type:
%%% 
%%%    source ./scripts/activate-toolchain.sh
%%% 
%%% Don't forget to [make clean] the easycrypt source tree
%%%
%%% --------------------------------------------------------------------
EOF
