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

ORIGINDIR=$(pwd)
BASEDIR=$(dirname "$0")
cd "${BASEDIR}" || exit 1

# Optional user-level env written by `hop setup` (does not override already-set variables)
HOP_USER_ENV="${XDG_CONFIG_HOME:-${HOME}/.config}/hop/hop-env.sh"
if [ -f "${HOP_USER_ENV}" ]; then
  # shellcheck source=/dev/null
  . "${HOP_USER_ENV}"
fi

# set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java
if [ -n "${HOP_JAVA_HOME}" ]; then
  _HOP_JAVA="${HOP_JAVA_HOME}/bin/java"
elif [ -n "${JAVA_HOME}" ]; then
  _HOP_JAVA="${JAVA_HOME}/bin/java"
else
  _HOP_JAVA="java"
fi

# Settings for all OSses
#
if [ -z "${HOP_OPTIONS}" ]; then
  HOP_OPTIONS="-Xmx2048m"
fi

# optional line for attaching a debugger
#
for arg in "$@"
do
  if [ "$arg" = "--dev-debug" ]
  then
    HOP_OPTIONS="${HOP_OPTIONS} -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5010"
  fi
  if [ "$arg" = "--dev-debug-wait" ]
  then
    HOP_OPTIONS="${HOP_OPTIONS} -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5010"
  fi
done

# Add HOP variables if they're set:
#
if [ -n "${HOP_AUDIT_FOLDER}" ]; then
  HOP_OPTIONS="${HOP_OPTIONS} -DHOP_AUDIT_FOLDER=${HOP_AUDIT_FOLDER}"
else
  HOP_OPTIONS="${HOP_OPTIONS} -DHOP_AUDIT_FOLDER=./audit"
fi
if [ -n "${HOP_CONFIG_FOLDER}" ]; then
  HOP_OPTIONS="${HOP_OPTIONS} -DHOP_CONFIG_FOLDER=${HOP_CONFIG_FOLDER}"
fi
if [ -n "${HOP_SHARED_JDBC_FOLDERS}" ]; then
  HOP_OPTIONS="${HOP_OPTIONS} -DHOP_SHARED_JDBC_FOLDERS=${HOP_SHARED_JDBC_FOLDERS}"
fi
if [ -n "${HOP_PLUGIN_BASE_FOLDERS}" ]; then
  HOP_OPTIONS="${HOP_OPTIONS} -DHOP_PLUGIN_BASE_FOLDERS=${HOP_PLUGIN_BASE_FOLDERS}"
fi
if [ -n "${HOP_PASSWORD_ENCODER_PLUGIN}" ]; then
  HOP_OPTIONS="${HOP_OPTIONS} -DHOP_PASSWORD_ENCODER_PLUGIN=${HOP_PASSWORD_ENCODER_PLUGIN}"
fi
if [ -n "${HOP_AES_ENCODER_KEY}" ]; then
  HOP_OPTIONS="${HOP_OPTIONS} -DHOP_AES_ENCODER_KEY=${HOP_AES_ENCODER_KEY}"
fi

HOP_OPTIONS="${HOP_OPTIONS} -DHOP_PLATFORM_RUNTIME=Run -DHOP_AUTO_CREATE_CONFIG=Y -DHOP_PLATFORM_OS="$(uname -s)
HOP_OPTIONS="${HOP_OPTIONS} --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED"

case $(uname -s) in
Linux)
  # Workaround for https://github.com/apache/hop/issues/4252
  # Related to https://github.com/eclipse-platform/eclipse.platform.swt/issues/639
  # And to some extent also https://github.com/eclipse-platform/eclipse.platform.swt/issues/790
  if [ "${XDG_SESSION_TYPE}" = "wayland" ]; then
    export GDK_BACKEND=x11
  fi
  if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then
    CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/arm64/*"
  else
    CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*"
  fi
  ;;
Darwin)
  if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then
    CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/arm64/*"
  else
    CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/x86_64/*"
  fi
  HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread"
  ;;
esac

# Optional versioned Spark client pack replaces default lib/spark-client on the classpath.
# Used by hop run (and other subcommands) the same as hop-run.sh.
if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}" ]; then
  CLASSPATH=$(echo "${CLASSPATH}" | sed 's|lib/spark-client/\*||g')
  CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*"
fi

# Beam plugin jar (and any legacy lib-beam/ tree). Current marketplace packaging (#7721/#7722)
# unpacks Beam SDKs into lib/core (already on CLASSPATH above); lib-beam is kept only for older
# installs that still have that layout.
if [ -d "plugins/engines/beam/lib-beam" ]; then
  CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*"
fi
# snowflake-jdbc is here, not in lib/core: the jar embeds its own zstd classes.
# This glob is the application classpath. Do not put a JDBC driver in this folder:
# DriverManager would return an app-classloader connection the database plugin cannot cast.
if [ -d "plugins/engines/beam/lib" ]; then
  CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib/*"
fi
if [ -d "plugins/engines/beam" ]; then
  # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent;
  # shell * includes jars and may pick non-jars; match historical lib/* style)
  CLASSPATH="${CLASSPATH}:plugins/engines/beam/*"
fi

# Shared jars installed beside an extra plugins folder (HOP_PLUGIN_BASE_FOLDERS) are not under
# this install's lib/core. The folder name must be "plugins"; its parent holds lib/core.
if [ -n "${HOP_PLUGIN_BASE_FOLDERS:-}" ]; then
  _hop_plugin_rest="${HOP_PLUGIN_BASE_FOLDERS}"
  while [ -n "${_hop_plugin_rest}" ]; do
    _hop_plugin_folder="${_hop_plugin_rest%%,*}"
    case "${_hop_plugin_rest}" in
      *,*) _hop_plugin_rest="${_hop_plugin_rest#*,}" ;;
      *) _hop_plugin_rest="" ;;
    esac
    _hop_plugin_folder="${_hop_plugin_folder#"${_hop_plugin_folder%%[![:space:]]*}"}"
    _hop_plugin_folder="${_hop_plugin_folder%"${_hop_plugin_folder##*[![:space:]]}"}"
    [ -z "${_hop_plugin_folder}" ] && continue
    if [ "$(basename "${_hop_plugin_folder}")" = "plugins" ]; then
      _hop_plugin_home="$(dirname "${_hop_plugin_folder}")"
      if [ -d "${_hop_plugin_home}/lib/core" ]; then
        case ":${CLASSPATH}:" in
          *":${_hop_plugin_home}/lib/core/*:"*) ;;
          *) CLASSPATH="${_hop_plugin_home}/lib/core/*:${CLASSPATH}" ;;
        esac
      fi
    fi
  done
  unset _hop_plugin_rest _hop_plugin_folder _hop_plugin_home
fi

# The JVM runs from the Hop installation, so user.dir is never where the user typed the command.
# Pass the directory they were in, for subcommands which take a path from them.
"${_HOP_JAVA}" ${HOP_OPTIONS} -Dhop.origin.dir="${ORIGINDIR}" -Djava.library.path="${LIBPATH}" -classpath "${CLASSPATH}" org.apache.hop.hop.Hop "$@"
EXITCODE=$?

cd "${ORIGINDIR}" || exit 1
exit $EXITCODE
