#!/bin/bash

deploy_dir="$(dirname "$(cd -- "$(dirname "$0")" > /dev/null 2>&1; pwd)")"

# source shflags
. "${deploy_dir}/tools/third/shflags"

# define FLAGS
DEFINE_string 'fusedaemon_combination_name' '' 'daemon name'
DEFINE_string 'fusedaemon_support_instance_list' '' 'instance daemon expected to support'
DEFINE_string 'fusedaemon_metrics_agent_name' "${FSX_AGENT_NAME:-}" 'fsx-agent name used as fusedaemon metric tag'
DEFINE_string 'fusedaemon_metrics_agent_group' "${FSX_AGENT_GROUP:-}" 'fsx-agent group used as fusedaemon metric tag'
DEFINE_string 'fusedaemon_metrics_agent_runtime_tag' "${FSX_AGENT_RUNTIME_TAG:-}" 'fsx-agent runtime tag used as fusedaemon metric tag'
DEFINE_boolean 'fusedaemon_enable_coredump' ${FLAGS_FALSE} 'Generate dump file when core' 'd'
DEFINE_string 'fusedaemon_launcher' '' 'launcher used for daemon'
DEFINE_string 'common_deploy_mode' 'default' 'deploy mode'
DEFINE_string 'common_conf_dir' '/opt/tmp/fsx' 'The target directory for fsx configuration'
DEFINE_string 'common_work_dir' '/opt/tmp/fsx' 'fsx work dir, if not set, will be set to ${FLAGS_common_conf_dir}.'
DEFINE_string 'common_log_dir' '/var/log/fsx' 'fsx log dir'
DEFINE_string 'fusedaemon_process_name' '' 'for pool mode, process name of fusedaemon'
DEFINE_string 'fusedaemon_generation' '0' 'managed pool unit generation'
DEFINE_integer 'common_socket_poller_num' 0 'fusedaemon socket poller count; 0 means use fusedaemon default'
DEFINE_string 'common_metrics_override_tags' "${FSX_COMMON_METRICS_OVERRIDE_TAGS:-}" 'comma-separated metric tag overrides in key=value form'
DEFINE_integer 'common_metrics_purge_metrics_timeout_ms' "${FSX_COMMON_METRICS_PURGE_METRICS_TIMEOUT_MS:-0}" 'metric inactivity timeout in milliseconds; 0 keeps the fusedaemon default'
DEFINE_boolean 'fusedaemon_vhost_user_fast_fail_on_umount' ${FLAGS_FALSE} 'Reject new vhost-user fuse requests during umount'
DEFINE_string 'fusedaemon_disable_transparent_huge_pages' '' 'whether to disable transparent huge pages'
DEFINE_string 'client_disable_refresh_ap_auth' '' 'whether to disable FSProxy SDK access-point auth refresh'
DEFINE_string 'fusedaemon_readdir_thicky_cache_size' '' 'readdir thicky cache size'
DEFINE_string 'fusedaemon_readdir_sparse_cache_size' '' 'readdir sparse cache size'
DEFINE_string 'fusedaemon_readdir_token_cache_size' '' 'readdir token cache size'
DEFINE_string 'fusedaemon_readdircache_full_session_limit' '' 'readdir full session limit'
DEFINE_string 'fusedaemon_vhost_user_max_queue_num' '' 'vhost-user maximum queue number'

DEFINE_string 'fusedaemon_combination_tag' '' '[[deprecated]] use common_deploy_mode instead, non-empty means old version'

# parse the command-line
FLAGS "$@" || exit $?
eval set -- "${FLAGS_ARGV}"

alias python=python3

if [ "x${FLAGS_fusedaemon_support_instance_list}" == "x" ]; then
    # TODO: Deprecate this style later
    if [ $# -ne 1 ]; then
        flags_help
        exit 1
    fi
    echo -e "Deprecated style detected! Check \033[0;33m$0 --help\033[0m instead"
    FLAGS_fusedaemon_combination_name=$1
    FLAGS_fusedaemon_support_instance_list=$1
fi
if [ "x${FLAGS_fusedaemon_combination_name}" == "x" ]; then
    echo -e "combination_name and support_instance_list SHOULD be set \033[0;33mBOTH\033[0m"
    flags_help
    exit 1
fi

if ! [[ "x${FLAGS_fusedaemon_launcher}" =~ ^x(|tz run)$ ]]; then
    echo -e "unknown fusedaemon_launcher \033[0;33m'${FLAGS_fusedaemon_launcher}'\033[0m"
    exit 1
fi


if [ "x${FLAGS_fusedaemon_combination_tag}" != "x" ]; then
    # old style: use common_conf_dir as common_work_dir, use fusedaemon_combination_tag as common_deploy_mode
    FLAGS_common_work_dir="${FLAGS_common_conf_dir}"
    FLAGS_common_deploy_mode="${FLAGS_fusedaemon_combination_tag}"
fi

ext_opts=()
ext_opts+=(--fusedaemon_combination_name="${FLAGS_fusedaemon_combination_name}")
ext_opts+=(--fusedaemon_support_instance_list="${FLAGS_fusedaemon_support_instance_list}")
if [ "x${FLAGS_fusedaemon_metrics_agent_name}" != "x" ]; then
    ext_opts+=(--fusedaemon_metrics_agent_name="${FLAGS_fusedaemon_metrics_agent_name}")
fi
if [ "x${FLAGS_fusedaemon_metrics_agent_group}" != "x" ]; then
    ext_opts+=(--fusedaemon_metrics_agent_group="${FLAGS_fusedaemon_metrics_agent_group}")
fi
if [ "x${FLAGS_fusedaemon_metrics_agent_runtime_tag}" != "x" ]; then
    ext_opts+=(--fusedaemon_metrics_agent_runtime_tag="${FLAGS_fusedaemon_metrics_agent_runtime_tag}")
fi
ext_opts+=(--common_deploy_mode="${FLAGS_common_deploy_mode}")
ext_opts+=(--common_deploy_dir="${deploy_dir}")
ext_opts+=(--common_conf_dir="${FLAGS_common_conf_dir}")
ext_opts+=(--common_work_dir="${FLAGS_common_work_dir}")
ext_opts+=(--fusedaemon_generation="${FLAGS_fusedaemon_generation}")
if [ "x${FLAGS_common_log_dir}" != "x${__flags_common_log_dir_default}" ]; then
    ext_opts+=(--common_log_dir="${FLAGS_common_log_dir}")
fi
if [ "x${FLAGS_fusedaemon_process_name}" != "x" ]; then
    ext_opts+=(--fusedaemon_process_name="${FLAGS_fusedaemon_process_name}")
fi
if [ ${FLAGS_common_socket_poller_num} -gt 0 ]; then
    ext_opts+=(--common_socket_poller_num="${FLAGS_common_socket_poller_num}")
fi
if [ -n "${FLAGS_common_metrics_override_tags}" ]; then
    ext_opts+=(--common_metrics_override_tags="${FLAGS_common_metrics_override_tags}")
fi
if [ ${FLAGS_common_metrics_purge_metrics_timeout_ms} -gt 0 ]; then
    ext_opts+=(--common_metrics_purge_metrics_timeout_ms="${FLAGS_common_metrics_purge_metrics_timeout_ms}")
fi
if [ ${FLAGS_fusedaemon_vhost_user_fast_fail_on_umount} -eq ${FLAGS_TRUE} ]; then
    ext_opts+=(--fusedaemon_vhost_user_fast_fail_on_umount)
fi
if [ -n "${FLAGS_fusedaemon_disable_transparent_huge_pages}" ]; then
    ext_opts+=("--fusedaemon_disable_transparent_huge_pages=${FLAGS_fusedaemon_disable_transparent_huge_pages}")
fi
if [ -n "${FLAGS_client_disable_refresh_ap_auth}" ]; then
    ext_opts+=("--common_client_disable_refresh_ap_auth=${FLAGS_client_disable_refresh_ap_auth}")
fi
if [ -n "${FLAGS_fusedaemon_readdir_thicky_cache_size}" ]; then
    ext_opts+=("--fusedaemon_readdir_thicky_cache_size=${FLAGS_fusedaemon_readdir_thicky_cache_size}")
fi
if [ -n "${FLAGS_fusedaemon_readdir_sparse_cache_size}" ]; then
    ext_opts+=("--fusedaemon_readdir_sparse_cache_size=${FLAGS_fusedaemon_readdir_sparse_cache_size}")
fi
if [ -n "${FLAGS_fusedaemon_readdir_token_cache_size}" ]; then
    ext_opts+=("--fusedaemon_readdir_token_cache_size=${FLAGS_fusedaemon_readdir_token_cache_size}")
fi
if [ -n "${FLAGS_fusedaemon_readdircache_full_session_limit}" ]; then
    ext_opts+=("--fusedaemon_readdircache_full_session_limit=${FLAGS_fusedaemon_readdircache_full_session_limit}")
fi
if [ -n "${FLAGS_fusedaemon_vhost_user_max_queue_num}" ]; then
    ext_opts+=("--fusedaemon_vhost_user_max_queue_num=${FLAGS_fusedaemon_vhost_user_max_queue_num}")
fi

coredump_env_file="/opt/fsx_enable_coredump"
if [ ${FLAGS_fusedaemon_enable_coredump} -eq ${FLAGS_FALSE} ] && [ ! -f ${coredump_env_file} ]; then
    export COREDUMP_CTL_NEED_CORE=no
    ulimit -c 0
else
    ulimit -c unlimited
    echo 1 > /proc/sys/kernel/core_uses_pid
fi

ext_opts+=(--common_enable_heartbeat="true")

daemon_run=true
handle_sigterm() {
    echo "receive sigterm signal"
    daemon_run=false
}
trap handle_sigterm SIGTERM

prctl_helper="${deploy_dir}/bin/fusedaemon_prctl_helper"
conf_file="${FLAGS_fusedaemon_combination_name}_${FLAGS_common_deploy_mode}.conf"
if [ -n "${FLAGS_fusedaemon_process_name}" ] && [ "${FLAGS_fusedaemon_generation}" = 0 ]; then
    conf_file="${FLAGS_fusedaemon_combination_name}_${FLAGS_fusedaemon_process_name}_${FLAGS_common_deploy_mode}.conf"
fi
fusedaemon_flagfile="${FLAGS_common_conf_dir}/conf/${FLAGS_fusedaemon_combination_name}/${conf_file}"
use_prctl_helper=true
if [ ! -x "${prctl_helper}" ]; then
    echo "missing executable prctl helper: ${prctl_helper}, fallback to direct launch" >&2
    use_prctl_helper=false
fi

export HDFS_FUSE_CONF=${FLAGS_common_conf_dir}/conf/hdfs/hdfs_fuse.conf
export CPP_HDFS_LOG_DIR=${FLAGS_common_log_dir}/fusedaemon/hdfs/hdfs_sdk
export HDFS_FUSE_LOG_DIR=${FLAGS_common_log_dir}/fusedaemon/hdfs/fusedaemon
while $daemon_run; do
    launch_cmd=()
    ulimit -n `cat /proc/sys/fs/nr_open`
    cd "${deploy_dir}/bin"
    if [ "x${FLAGS_fusedaemon_launcher}" != "x" ]; then
        read -r -a launcher_args <<< "${FLAGS_fusedaemon_launcher}"
        launch_cmd+=("${launcher_args[@]}")
    fi
    launch_cmd+=(./fusedaemon "${ext_opts[@]}")
    if ${use_prctl_helper}; then
        prctl_helper_opts=()
        if [ -f "${fusedaemon_flagfile}" ]; then
            prctl_helper_opts+=(--flagfile="${fusedaemon_flagfile}")
        fi
        if [ -n "${FLAGS_fusedaemon_disable_transparent_huge_pages}" ]; then
            prctl_helper_opts+=("--fusedaemon_disable_transparent_huge_pages=${FLAGS_fusedaemon_disable_transparent_huge_pages}")
        fi
        "${prctl_helper}" "${prctl_helper_opts[@]}" -- "${launch_cmd[@]}"
    else
        "${launch_cmd[@]}"
    fi
done
