#!/bin/bash -x

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eu
set -o pipefail

# Private methods:

function _log() {
  local msg="$1"
  echo "[$(date)] -- ${msg}"
}

function _error() {
  local msg="$1"
  1>&2 _log "ERROR: $msg"
  exit 1
}

function _get_code_root() {
  git rev-parse --show-toplevel
}

function _get_maven_property_value() {
  local property="$1";

  (
    cd "$(_get_code_root)" \
    && mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression="${property}"  -q -DforceStdout \
      | sed 's/%$//'
  )
}

function _get_druid_version() {
  _get_maven_property_value "project.version"
}

function _get_zookeeper_version() {
  _get_maven_property_value "zookeeper.version"
}

function _download_zookeeper() {
  local dest="$1"
  local zk_version
  zk_version="$(_get_zookeeper_version)"
  #zk_tar=apache-zookeeper-${zk_version}-bin # for zk 3.5.x
  zk_tar=zookeeper-${zk_version} # for zk 3.4.x

  _log "Downloading zookeeper"
  curl -s "https://archive.apache.org/dist/zookeeper/zookeeper-${zk_version}/$zk_tar.tar.gz" \
    | tar xz \
  && rm -rf "$dest" \
  && mv "$zk_tar" "$dest" \
  && rm -f "$zk_tar"
}

function _build_distribution() {
  _log "Building druid distribution"

  (
    # Add HEAD as an allowed HTTP method since this is how we check when the Druid service is ready.
    cd "$(_get_code_root)" \
    && mvn -Pdist,skip-static-checks,skip-tests -Dmaven.javadoc.skip=true -q -T1C install \
    && cd distribution/target \
    && tar xzf "apache-druid-$(_get_druid_version)-bin.tar.gz" \
    && echo -e "\n\ndruid.server.http.allowedHttpMethods=[\"HEAD\"]" >> apache-druid-$(_get_druid_version)/conf/druid/single-server/micro-quickstart/_common/common.runtime.properties
  )
}

function _wait_for_200_response() {
  local url="$1"
  local delay="$2"
  local tries="$3"
  local counter=0

  _log "Waiting for 200 response from ${url}"

  until curl --output /dev/null --silent --head --fail "${url}"; do
    if [ "${counter}" -eq "${tries}" ];then
      _error "Max of ${tries} tries exceeded"
    fi

    printf '.'
    counter=$((counter+1))
    sleep "$delay"
  done

  _log "${url} is ready"
}

DRUID_PID_FILE=".druid.pid"

# Public methods:

function build() {
  _log "Building druid"
  _build_distribution \
  && _download_zookeeper "$(_get_code_root)/distribution/target/apache-druid-$(_get_druid_version)/zk"
  _log "Done building druid"
}

function start() {
  _log "Starting druid"

  if [ -f "${DRUID_PID_FILE}" ]; then
     _error "${DRUID_PID_FILE} exists with pid '$(<${DRUID_PID_FILE})'. Either shutdown druid or delete this file."
  fi

  "$(_get_code_root)/distribution/target/apache-druid-$(_get_druid_version)/bin/start-micro-quickstart" > /dev/null &
  local pid="$!"
  echo "$pid" > "$DRUID_PID_FILE"
  _log "Druid started with pid ${pid}"

  _wait_for_200_response "http://localhost:8888/unified-console.html" 3 20
}

function stop() {
  _log "Stopping druid"
  if [ -f "${DRUID_PID_FILE}" ]; then
    local pid
    pid="$(<${DRUID_PID_FILE})"
    kill "$pid"
    rm "${DRUID_PID_FILE}"
    _log "Stopped pid ${pid}"
  else
    _log "${DRUID_PID_FILE} file does not exist"
  fi
}

# Execute public method (passed as script argument)
"$@"
