#!/bin/bash
CQL_HOSTNAMES=${TH_CQL_HOSTNAMES:-cassandra}
BDB_DIRECTORY=${TH_BDB_DIRECTORY:-/data/db}
INDEX_DIRECTORY=${TH_INDEX_DIRECTORY:-/data/index}
HDFS_URL=${TH_HDFS_URL}
STORAGE_DIRECTORY=${TH_STORAGE_DIRECTORY:-/data/files}
test "${TH_NO_CONFIG_SECRET}" == 1
CONFIG_SECRET=$?
SECRET=${TH_SECRET}
SHOW_SECRET=${TH_SHOW_SECRET:-0}
test "${TH_NO_CONFIG_DB}" == 1
CONFIG_DB=$?
test "${TH_NO_CONFIG_STORAGE}" == 1
CONFIG_STORAGE=$?
test "${TH_NO_CONFIG_CORTEX}" == 1
CONFIG_CORTEX=$?
CORTEX_HOSTNAMES=${TH_CORTEX_HOSTNAMES:-cortex}
CORTEX_PROTO=${TH_CORTEX_PROTO:-http}
CORTEX_PORT=${TH_CORTEX_PORT:-9001}
test "${TH_NO_CONFIG}" == 1
CONFIG=$?
CONFIG_FILE=${TH_CONFIG_FILE:-/etc/thehive/application.conf}
CORTEX_KEYS=${TH_CORTEX_KEYS}
MIGRATE=${TH_MIGRATE:-0}
CLONER=${TH_CLONER:-0}

function usage {
  cat <<- _EOF_
    Available options:
    --config-file <file>                        | configuration file path
    --no-config                                 | do not try to configure TheHive (add secret and elasticsearch)
    --no-config-secret                          | do not add random secret to configuration
    --secret <secret>                           | secret to secure sessions
    --show-secret                               | show the generated secret
    --no-config-db                              | do not configure database automatically
    --cql-hostnames <host>,<host>,...           | resolve these hostnames to find cassandra instances
    --cql-username <username>                   | username of cassandra database
    --cql-password <password>                   | password of cassandra database
    --bdb-directory <path>                      | location of local database, if cassandra is not used (default: /data/db)
    --no-config-storage                         | do not configure storage automatically
    --hdfs-url <url>                            | url of hdfs name node
    --storage-directory <path>                  | location of local storage, if hdfs is not used (default: /data/files)
    --no-config-cortex                          | do not add Cortex configuration
    --cortex-proto <proto>                      | define protocol to connect to Cortex (default: http)
    --cortex-port <port>                        | define port to connect to Cortex (default: 9001)
    --cortex-hostnames <host>,<host>,...        | resolve this hostname to find Cortex instances
    --cortex-keys <key>,<key>,...               | define Cortex key
    migrate <param> <param> ...                 | run migration tool
    cloner <param> <param> ...                  | run cloner tool
_EOF_
  exit 1
}


STOP=0
while test $# -gt 0 -a "${STOP}" = 0
do
  case "$1" in
    "--config-file")       shift; CONFIG_FILE=$1 ;;
    "--no-config")         CONFIG=0 ;;
    "--no-config-secret")  CONFIG_SECRET=0 ;;
    "--secret")            shift; SECRET=$1 ;;
    "--show-secret")       SHOW_SECRET=1 ;;
    "--no-config-db")      CONFIG_DB=0 ;;
    "--cql-hostnames")     shift; CQL_HOSTNAMES=$1 ;;
    "--cql-username")      shift; CQL_USERNAME=$1 ;;
    "--cql-password")      shift; CQL_PASSWORD=$1 ;;
    "--bdb-directory")     shift; BDB_DIRECTORY=$1 ;;
    "--index-directory")   shift; INDEX_DIRECTORY=$1 ;;
    "--no-config-storage") CONFIG_STORAGE=0 ;;
    "--hdfs-url")          shift; HDFS_URL=$1 ;;
    "--storage-directory") shift; STORAGE_DIRECTORY=$1 ;;
    "--no-config-cortex")  CONFIG_CORTEX=0 ;;
    "--cortex-proto")      shift; CORTEX_PROTO=$1 ;;
    "--cortex-port")       shift; CORTEX_PORT=$1 ;;
    "--cortex-hostnames")  shift; CORTEX_HOSTNAMES=$1 ;;
    "--cortex-keys")       shift; CORTEX_KEYS=$1 ;;
    "--")                  STOP=1 ;;
    "migrate")             MIGRATE=1; STOP=1 ;;
    "cloner")              CLONER=1; STOP=1 ;;
    *)                     echo param is -"$1"-; usage
  esac
  shift
done

if test "${MIGRATE}" = 1
then
  bin/migrate "$@"
  exit $?
fi

if test "${CLONER}" = 1
then
  bin/cloner "$@"
  exit $?
fi

if test "${CONFIG}" = 1
then
  CONFIG_FILE=$(mktemp --tmpdir thehive-XXXXXX.conf)
  if test "${CONFIG_SECRET}" = 1
  then
    if test -z "${SECRET}"
    then
      SECRET=$(dd if=/dev/urandom bs=1024 count=1 | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1)
      test "${SHOW_SECRET}" = 1 && echo "Using secret: ${SECRET}"
    fi
    echo "play.http.secret.key = \"${SECRET}\"" >> "${CONFIG_FILE}"
  fi

  if test "${CONFIG_DB}" = 1
  then
    IFS=',' read -r -a CQL_HOSTS <<< "${CQL_HOSTNAMES}"
    declare -a CQL
    for C in "${CQL_HOSTS[@]}"
    do
      for IP in $(getent ahostsv4 "$C" | awk '{ print $1 }' | sort -u)
      do
        CQL+=("$IP")
      done
    done
    echo "db.janusgraph {" >> "${CONFIG_FILE}"
    if test "${#CQL[@]}" = 0
    then
      echo "Local database in ${BDB_DIRECTORY} is be used"
      mkdir -p "${BDB_DIRECTORY}"
      echo "storage.backend = berkeleyje"             >> "${CONFIG_FILE}"
      echo "storage.directory = \"${BDB_DIRECTORY}\"" >> "${CONFIG_FILE}"
      echo "berkeleyje.freeDisk = 1"                  >> "${CONFIG_FILE}"
      if test -e "${BDB_DIRECTORY}"
      then
        test -w "${BDB_DIRECTORY}" || echo "WARNING the directory used to store database ($BDB_DIRECTORY) is not writable"
      else
        mkdir -p "${BDB_DIRECTORY}" || echo "WARNING the directory used to store database ($BDB_DIRECTORY) is not writable"
      fi
    else
      echo "Using cassandra address = ${CQL[*]}"
      echo "storage.backend = cql"            >> "${CONFIG_FILE}"
      if [[ -n $CQL_USERNAME && -n $CQL_PASSWORD ]]
      then
        echo "storage.username = \"${CQL_USERNAME}\"" >> "${CONFIG_FILE}"
        echo "storage.password = \"${CQL_PASSWORD}\"" >> "${CONFIG_FILE}"
        echo "Using ${CQL_USERNAME} as cassandra username and ${CQL_PASSWORD} as its password"
      fi
      echo "storage.cql.cluster-name = thp"   >> "${CONFIG_FILE}"
      echo "storage.cql.keyspace = thehive"   >> "${CONFIG_FILE}"
      echo "storage.hostname = ["             >> "${CONFIG_FILE}"
      printf '%s\n' "${CQL_HOSTS[@]}"         >> "${CONFIG_FILE}"
      echo "]"                                >> "${CONFIG_FILE}"
      echo "Waiting until Cassandra DB is up"
      sleep 30   # Sleep until cassandra Db is up
    fi
    echo "index.search.backend = lucene"                   >> "${CONFIG_FILE}"
    echo "index.search.directory = \"${INDEX_DIRECTORY}\"" >> "${CONFIG_FILE}"
    if test -e "${INDEX_DIRECTORY}"
    then
      test -w "${INDEX_DIRECTORY}" || echo "WARNING the directory used to store index ($INDEX_DIRECTORY) is not writable"
    else
      mkdir -p "${INDEX_DIRECTORY}" || echo "WARNING the directory used to store index ($INDEX_DIRECTORY) is not writable"
    fi
    echo "}" >> "${CONFIG_FILE}"
  fi

  if test "${CONFIG_STORAGE}" = 1
  then
    echo "storage {" >> "${CONFIG_FILE}"
    if test -n "${HDFS_URL}"
    then
      echo "Using HDFS ${HDFS_URL}"
      echo "provider: hdfs"          >> "${CONFIG_FILE}"
      echo "hdfs {"                  >> "${CONFIG_FILE}"
      echo "root: \"${HDFS_URL}\""   >> "${CONFIG_FILE}"
      echo "location: \"/thehive\""  >> "${CONFIG_FILE}"
      echo "username: thehive"       >> "${CONFIG_FILE}"
      echo "}"                       >> "${CONFIG_FILE}"
    else
      echo "Using local storage in ${STORAGE_DIRECTORY}"
      mkdir -p "${STORAGE_DIRECTORY}"
      echo "provider: localfs"                           >> "${CONFIG_FILE}"
      echo "localfs.directory: \"${STORAGE_DIRECTORY}\"" >> "${CONFIG_FILE}"
      if test -e "${STORAGE_DIRECTORY}"
      then
        test -w "${STORAGE_DIRECTORY}" || echo "WARNING the directory used to store files ($STORAGE_DIRECTORY) is not writable"
      else
        mkdir -p "${STORAGE_DIRECTORY}" || echo "WARNING the directory used to store files ($STORAGE_DIRECTORY) is not writable"
      fi
    fi
    echo "}" >> "${CONFIG_FILE}"
  fi

  if test "${CONFIG_CORTEX}" = 1
  then
    declare -a CORTEX_URLS
    IFS=',' read -r -a CH <<< "${CORTEX_HOSTNAMES}"
    IFS=',' read -r -a CK <<< "${CORTEX_KEYS}"
    for C in "${CH[@]}"
    do
      test -n "${C}" && CORTEX_URLS+=("${CORTEX_PROTO}://${C}:${CORTEX_PORT}")
    done
    if test ${#CORTEX_URLS[@]} -gt 0
    then
      echo "play.modules.enabled += org.thp.thehive.connector.cortex.CortexModule" >> "${CONFIG_FILE}"
      echo "cortex.servers = [" >> "${CONFIG_FILE}"
      I=0
      for C in "${CORTEX_URLS[@]}"
      do
        echo "Add Cortex cortex${I}: ${C}"
        echo "{"                   >> "${CONFIG_FILE}"
        echo "name = cortex${I}"   >> "${CONFIG_FILE}"
        echo "url = \"$C\""        >> "${CONFIG_FILE}"
        echo "auth {"              >> "${CONFIG_FILE}"
        echo "type = \"bearer\""   >> "${CONFIG_FILE}"
        echo "key = \"${CK[$I]}\"" >> "${CONFIG_FILE}"
        echo "}"                   >> "${CONFIG_FILE}"
        echo "}"                   >> "${CONFIG_FILE}"
        I=$((I+1))
      done
      echo "]"  >> "${CONFIG_FILE}"
    fi
  fi

  echo "include file(\"/etc/thehive/application.conf\")" >> "${CONFIG_FILE}"
fi

bin/thehive \
  -Dconfig.file="${CONFIG_FILE}" \
  -Dlogger.file=/etc/thehive/logback.xml \
  -Dpidfile.path=/dev/null \
  "$@"
PID=$!
trap 'kill -SIGTERM "${PID}"; wait "${PID}"; exit 143' SIGTERM SIGINT
wait ${PID}
