#!/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 _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,bundle-contrib-exts,skip-static-checks,skip-tests -Dforbiddenapis.skip=true -Dcheckstyle.skip=true -Dpmd.skip=true -Dmaven.javadoc.skip=true -Danimal.sniffer.skip=true -Denforcer.skip=true -Dcyclonedx.skip=true -q -T1C install \
    && cd distribution/target \
    && tar xzf "apache-druid-$(_get_druid_version)-bin.tar.gz" \
    && cd apache-druid-$(_get_druid_version) \
    && mkdir -p extensions/druid-testing-tools \
    && cp "$(_get_code_root)/extensions-core/testing-tools/target/druid-testing-tools-$(_get_druid_version).jar" extensions/druid-testing-tools/ \
    && mkdir -p extensions/druid-compressed-bigdecimal \
    && cp "$(_get_code_root)/extensions-contrib/compressed-bigdecimal/target/druid-compressed-bigdecimal-$(_get_druid_version).jar" extensions/druid-compressed-bigdecimal/ \
    && echo -e "\n\ndruid.extensions.loadList=[\"druid-hdfs-storage\", \"druid-kafka-indexing-service\", \"druid-multi-stage-query\", \"druid-testing-tools\", \"druid-bloom-filter\", \"druid-datasketches\", \"druid-histogram\", \"druid-stats\", \"druid-compressed-bigdecimal\", \"druid-parquet-extensions\", \"druid-deltalake-extensions\"]" >> conf/druid/auto/_common/common.runtime.properties \
    && echo -e "\n\ndruid.server.http.allowedHttpMethods=[\"HEAD\"]" >> conf/druid/auto/_common/common.runtime.properties \
    && echo -e "\n\ndruid.export.storage.baseDir=/" >> conf/druid/auto/_common/common.runtime.properties \
    && echo -e "\n\ndruid.msq.dart.enabled=true" >> conf/druid/auto/_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
  _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

  export DRUID_SKIP_JAVA_CHECK=1 # Make it simpler to develop the web console when localhost is on JDK11
  "$(_get_code_root)/distribution/target/apache-druid-$(_get_druid_version)/bin/start-druid" -m 16g > /dev/null &
  local pid="$!"
  echo "$pid" > "$DRUID_PID_FILE"
  _log "Druid started with pid ${pid}"

  _wait_for_200_response "http://localhost:8888/proxy/coordinator/status" 3 30
  _wait_for_200_response "http://localhost:8888/unified-console.html" 3 10
}

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)
"$@"
