#!/bin/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.


# This script runs the Impala shell. Python is required.
#
# This contains installations for different versions of Python in
# install_py${PYTHON_VERSION} directories (e.g. install_py3.8).

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
SHELL_HOME=${IMPALA_SHELL_HOME:-${SCRIPT_DIR}}

# Set the envrionment's locale settings to allow for utf-8 compatibility
export LC_CTYPE=${LC_CTYPE:-en_US.UTF-8}

# If the user specified IMPALA_PYTHON_EXECUTABLE and it exists, use it.
# If it doesn't exist and IMPALA_SHELL_PYTHON_FALLBACK is false, exit with an error
# message. Otherwise, fall back to the regular path. IMPALA_SHELL_PYTHON_FALLBACK
# defaults to true to match historical behavior.
IMPALA_SHELL_PYTHON_FALLBACK=${IMPALA_SHELL_PYTHON_FALLBACK:-true}
PYTHON_EXE=""
if [[ -n "${IMPALA_PYTHON_EXECUTABLE}" ]]; then
  if command -v "${IMPALA_PYTHON_EXECUTABLE}" > /dev/null; then
    PYTHON_EXE="${IMPALA_PYTHON_EXECUTABLE}"
  elif ! ${IMPALA_SHELL_PYTHON_FALLBACK} ; then
    echo "Couldn't find IMPALA_PYTHON_EXECUTABLE=${IMPALA_PYTHON_EXECUTABLE}."
    exit 1
  fi
fi

# If IMPALA_PYTHON_EXECUTABLE isn't specified or doesn't exist, try the regular
# "python3" and "python" executables. Since Python 2 is deprecated, prefer "python3"
# to "python" (though "python" may actually point to Python 3).
if [[ -z "${PYTHON_EXE}" ]]; then
  if command -v python3 > /dev/null; then
    PYTHON_EXE=python3
  elif command -v python > /dev/null; then
    PYTHON_EXE=python
  else
    if [[ -n "${IMPALA_PYTHON_EXECUTABLE}" ]]; then
      echo "Couldn't find IMPALA_PYTHON_EXECUTABLE=${IMPALA_PYTHON_EXECUTABLE}."
    fi
    echo "Couldn't find python3 or python on the PATH"
    exit 1
  fi
fi

# impala-shell is installed in /install_py${PYTHON_VERSION}
PYTHON_VERSION=$("${PYTHON_EXE}" -c 'import sys; \
  print("{}.{}".format(sys.version_info.major, sys.version_info.minor))')
if [ ! -d "${SHELL_HOME}/install_py${PYTHON_VERSION}" ]; then
  # List all install_py* dirs, remove install_py prefix, and join into a comma-separated
  # string.
  dirs=( $(cd ${SHELL_HOME} && echo install_py*) )
  vers="${dirs[@]#install_py}"
  pretty="$(printf "%s, " ${vers[@]})"
  echo "This impala-shell package was not built to support Python ${PYTHON_VERSION}." \
       "Supported Python versions are: ${pretty%, }."
  exit 1
fi

PYTHONIOENCODING='utf-8' PYTHONPATH="${SHELL_HOME}/install_py${PYTHON_VERSION}" \
  exec ${PYTHON_EXE} -m "impala_shell.impala_shell" "$@"
