#!/usr/bin/env bash
#
# vim:et:ft=sh:sts=2:sw=2
#
#/**
# * 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.
# */

BINDIR=${BK_BINDIR:-"`dirname "$0"`"}

source ${BINDIR}/common.sh

DOCKER_COMPOSE=docker-compose

DATA_ROOT_DIR=${BK_DATA_DIR:-"${BK_HOME}/data"}
mkdir -p ${DATA_ROOT_DIR}

function gen_metadata_service_section() {
  local cluster=$1
  local image=$2
  cat <<EOF
  metadata-service:
    image: ${image}
    hostname: metadata-service
    command: ["zookeeper"]
    environment:
      - ZK_dataDir=/data/zookeeper/data
      - ZK_dataLogDir=/data/zookeeper/txlog
      - ZK_standaloneEnabled=true
    ports:
      - "9990:9990"
      - "2181:2181"
    volumes:
      - "${DATA_ROOT_DIR}/${cluster}/zookeeper/data:/data/zookeeper/data"
      - "${DATA_ROOT_DIR}/${cluster}/zookeeper/txlog:/data/zookeeper/txlog"
EOF
}

function gen_bookie_section() {
  local cluster=$1
  local bookie_name=$2
  local bookie_port=$3
  local bookie_http_port=$4
  local bookie_grpc_port=$5
  local image=$6
  cat <<EOF
  ${bookie_name}:
    image: ${image}
    depends_on:
      - metadata-service
    environment:
      # metadata service
      - BK_zkServers=metadata-service
      - BK_zkLedgersRootPath=/ledgers
      - BK_metadataServiceUri=zk://metadata-service/ledgers
      # bookie
      - BK_DATA_DIR=/data/bookkeeper
      - BK_advertisedAddress=${bookie_name}
      # bookie http
      - BK_httpServerEnabled=true
      # stream storage
      - BK_extraServerComponents=org.apache.bookkeeper.stream.server.StreamStorageLifecycleComponent
    ports:
      - "${bookie_port}:3181"
      - "${bookie_http_port}:8080"
      - "${bookie_grpc_port}:4181"
    volumes:
      - "${DATA_ROOT_DIR}/${cluster}/${bookie_name}/journal:/data/bookkeeper/journal"
      - "${DATA_ROOT_DIR}/${cluster}/${bookie_name}/ledgers:/data/bookkeeper/ledgers"
EOF
}

function generate_docker_compose_file() {
  local cluster=$1
  local num_bookies=$2
  local image=$3
  local docker_compose_file="${DATA_ROOT_DIR}/${cluster}/docker-compose.yml"

  local metadata_service_section=$(gen_metadata_service_section ${cluster} ${image})
    
  echo "version: '3'"                 >  ${docker_compose_file}
  echo ""                             >> ${docker_compose_file}
  echo "services:"                    >> ${docker_compose_file}
  echo ""                             >> ${docker_compose_file}
  echo "${metadata_service_section}"  >> ${docker_compose_file}
  echo ""                             >> ${docker_compose_file}
  local BI=0
  while [ ${BI} -lt $((num_bookies)) ]; do
    local bookie_port=$((3181 + BI))
    local bookie_http_port=$((8080 + BI))
    local bookie_grpc_port=$((4181 + BI))
    local bookie_section=$(gen_bookie_section ${cluster} "bookie-${BI}" ${bookie_port} ${bookie_http_port} ${bookie_grpc_port} ${image})
    echo "${bookie_section}"        >> ${docker_compose_file}
    let BI=BI+1
  done
}

function show_help() {
  cat <<EOF
Usage: standalone.docker-compose [-c <cluster_name>] [-h] <action:[up|down]>
EOF
}

# main entrypoint

CLUSTER_NAME="bk-standalone-dc"
OPTIND=1
IMAGE=${IMAGE:-"apachebookkeeper/bookkeeper-current"}
NUM_BOOKIES=${NUM_BOOKIES:-"3"}

while getopts "h:c:" opt; do
  case "${opt}" in
  c )
    CLUSTER_NAME=${OPTARG}
    echo "use cluster = '${CLUSTER_NAME}'."
    ;;
  h|\? )
    show_help
    exit 1
    ;;
  esac
done

shift $((OPTIND-1))

[ "${1:-}" = "--" ] && shift

if [ $# -le 0 ]; then
  show_help
  exit 1
fi

ACTION=$1
DOCKER_COMPOSE_OPTS=""
case "${ACTION}" in
  up)
    DOCKER_COMPOSE_OPTS="--detach"
    ;;
  down)
    ;;
  *)
    echo "Unknown action : ${ACTION}"
    show_help
    exit 1
    ;;
esac

CLUSTER_DATA_ROOT="${DATA_ROOT_DIR}/${CLUSTER_NAME}"
mkdir -p ${CLUSTER_DATA_ROOT}

# generate docker compose file 
DOCKER_COMPOSE_FILE="${CLUSTER_DATA_ROOT}/docker-compose.yml"

if [ ! -f ${DOCKER_COMPOSE_FILE} ]; then
  generate_docker_compose_file ${CLUSTER_NAME} ${NUM_BOOKIES} ${IMAGE}
fi

cd ${CLUSTER_DATA_ROOT}



${DOCKER_COMPOSE} $@ ${DOCKER_COMPOSE_OPTS}

if [ $? == 0 -a "${ACTION}" == "up" ]; then
    echo ""
    echo "Standalone cluster '${CLUSTER_NAME}' is up running."
    echo "Use following uris to connect to standalone cluster:"
    echo ""
    echo "  - metadata service uri = 'zk://localhost/ledgers'"
    echo "  - dlog uri             = 'distributedlog://localhost/distributedlog'"
fi
exit $?
