#!/usr/bin/env bash

## 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.

function log() {
  echo " $(date $DATE)" "$@"
}

function debug() {
 if [ $DEBUG = 1 ]; then
   log "DEBUG" "$@"
 fi
}

function info() {
  log "INFO" "$@"
}

function warn() {
  log "WARN" "$@" 1>&2
}

function error() {
  log "ERROR" "$@" 1>&2
}

function abort() {
  local EXIT=$1

  # Trick to check for numeric
  # -eq only returns true if the value is integer equals
  if [ "$EXIT" -eq "$EXIT" ]; then
    # Can use the provided exit code
    shift
  else
    # Caller forgot to provide an exit code so use default of 1
    EXIT=1
  fi

  # Log error and exit
  error "$@"
  exit $EXIT
}

function getSize() {
  ls -l $1 | awk '{print $5}'
}

function getDriveInfo() {
  local DIR=$1

  local DRIVE_INFO=$(df -k "$DIR" | tail -n +2)
  if [ -z "${DRIVE_INFO}" ]; then
    abort 1 "Failed to get drive information for $DIR"
  fi
  local DISK=$(echo $DRIVE_INFO | awk '{print $1}')
  local FREE_BYTES=$(echo $DRIVE_INFO | awk '{print $4}')
  FREE_BYTES="$(($FREE_BYTES * 1024))"
  local USED_PERCENT=$(echo $DRIVE_INFO | awk '{print $5}')
  USED_PERCENT=${USED_PERCENT/"%"/}
  local FREE_PERCENT=$((100 - $USED_PERCENT))

  local INFO=()
  INFO[0]="$DISK"
  INFO[1]="$USED_PERCENT"
  INFO[2]="$FREE_PERCENT"
  INFO[3]="$FREE_BYTES"

  echo ${INFO[@]}
}

function getFreeMem() {
  # May be called from a script where exit on error is set
  # in which case disable for the life of this function
  set +e

  local FREE_MEM=-1
  case "$OSTYPE" in
    darwin*)
      # Have to get this from top
      FREE_MEM=$(top -l 1 | grep PhysMem | awk '{print $6}')
      MEM_UNIT=${FREE_MEM:${#FREE_MEM}-1:1}
      FREE_MEM=${FREE_MEM%${MEM_UNIT}}
      case "${MEM_UNIT}" in
        K)
          # Unlikely but let's cover our bases
          FREE_MEM=$((${FREE_MEM} * 1024))
          ;;
        M)
          FREE_MEM=$((${FREE_MEM} * 1024 * 1024))
          ;;
        G)
          FREE_MEM=$((${FREE_MEM} * 1024 * 1024 * 1024))
          ;;
        T)
          # Probably a ways off but let's be future proof
          FREE_MEM=$((${FREE_MEM} * 1024 * 1024 * 1024 * 1024))
          ;;
        *)
          # Unable to determine
          FREE_MEM=-1
          ;;
        esac
      ;;
    linux*)
      # Try to use free if available
      which free >/dev/null 2>&1
      if [ $? -eq 0 ]; then
        # Have free available
        FREE_MEM=$(free -b)

        # Check the output
        # 2.x kernels produce just an integer
        # 3.x kernels produce detailed information
        case "$FREE_MEM" in
          ''|*[!0-9]*)
            # Clean up free output on 3.x kernels
            FREE_MEM=$(echo "$FREE_MEM" | tail -n +2 | head -n 1 | awk '{print $4}')
        esac

        # Final check that the output is numeric
        if [ ! "$FREE_MEM" -eq "$FREE_MEM" ] 2>/dev/null; then
          # Non-numeric
          FREE_MEM=-1
        fi
      fi
      ;;
  esac

  set -e

  echo "$FREE_MEM"
}

function resolveLink() {
  local NAME=$1

  if [ -L "$NAME" ]; then
    case "$OSTYPE" in
      darwin*|bsd*)
        # BSD style readlink behaves differently to GNU readlink
        # Have to manually follow links
        while [ -L "$NAME" ]; do
          NAME=$(readlink -- "$NAME")
        done
        ;;
      *)
        # Assuming standard GNU readlink with -f for
        # canonicalize
        NAME=$(readlink -f -- "$NAME")
        ;;
    esac
  fi

  echo "$NAME"
}

function resolveLinks() {
  local NAME=$1

  if [ -L "$NAME" ]; then
    NAME=$(resolveLink "$NAME")
  elif [[ "$NAME" == *"/" ]]; then
    # If the path ends in a / test -L will report false even
    # if the path is actually a symbolic link
    # So check if the name without the trailing / is a link and if
    # so resolve it
    if [ -L "${NAME%/}" ]; then
      NAME=${NAME%/}
      NAME=$(resolveLink "$NAME")
    fi
  fi
  echo "$NAME"
}

function makeAbsolute() {
  local NAME=$1

  # Follow links
  NAME=$(resolveLinks "$NAME")

  # Put back trailing slash
  # Do this before we make the path absolute or we'll absolutize wrong
  if [ -d "$NAME" ]; then
    if [[ "$NAME" != *"/" ]]; then
      NAME="${NAME}/"
    fi
  fi

  if [[ "$NAME" != "/"* ]]; then
    # Now make absolute
    case "$OSTYPE" in
      darwin*|bsd*)
        # BSD style readlink does not support the -f for canonicalization
        # so have to do this via cd, pwd and basename
        local FILENAME=$(basename "$NAME")
        NAME=$(cd $(dirname "$NAME"); pwd)
        NAME="$NAME/$FILENAME"
        ;;
      *)
        # Otherwise assume standard GNU readlink
        NAME=$(readlink -f -- "$NAME")
        ;;
    esac

    # Put back trailing slash
    if [ -d "$NAME" ]; then
      if [[ "$NAME" != *"/" ]]; then
        NAME="${NAME}/"
      fi
    fi
  fi

  echo "$NAME"
}

#DATE="+%Y-%m-%dT%H:%M:%S%:z"
DATE="+%H:%M:%S"

# Package for the command wrappers.
PKG=tdb.bulkloader2
