#!/bin/bash

. ./libinstall.sh

APP="fusion"
APP_NAME="Fusion"

FORCE="False"
INTERACTIVE="True"

PROD_DIR="/var/www/html/$APP"
BACKEND_DIR="/usr/local/$APP"
ETC_DIR="/etc/$APP"
LIB_DIR="/var/lib/$APP"

INSTALL_PATH="$(pwd)"
INSTALLED_FLAG="$BACKEND_DIR/.installed"

IP_ADDRESS="$(hostname -I | awk '{print $1}')"

# Pinning InfluxDB OSS v1.12.2-4
# - Currently this is only intended for dev and beta while InfluxDB 1.12.3 is broken
# - Hopefully InfluxDB will release a fix to 1.12.3 before MVP release, otherwise
#   we will need to apply the patch Sandor did for NNA
INFLUXDB_VERSION="1.12.2-4"

do_install_check

install_help() {
    cat <<-EOF

        Nagios $APP_NAME Installer
        Copyright (c) 2026, Nagios Enterprises LLC.
        License:
            Nagios Software License <http://assets.nagios.com/licenses/nagios_software_license.txt>

        Usage: ./fullinstall [options...]

        Options:
            -h | --help
                Display this help text
            -f | --force
                Force install (remove existing installation)
            -n | --non-interactive
                Assume defaults for all questions (for scripted installs)
EOF
}

create_users() {
    echo_c "Creating the $APP user..." "$BLUE"
    add_user "$APP"
    add_group "$APP"
    add_to_groups "$APP" "$APP"
}

prereqs() {
    echo_c "Installing prerequisites..." "$BLUE"

    shared_pkgs="php php-fpm php-xml php-mbstring php-curl php-ldap unzip acl sysstat gettext"

    if [[ "$distro" == "ubuntu" || "$distro" == "debian" ]]; then
        prereqs_debian
    else
        prereqs_el
    fi
}

prereqs_debian() {
    pkgs="apache2 php-mysql mariadb-server uuid-runtime supervisor curl sudo cron"

    case "$(uname -m)" in
        x86_64)  influx_deb_arch="amd64" ;;
        aarch64) influx_deb_arch="arm64" ;;
        *) echo_c "ERROR: Unsupported architecture for InfluxDB .deb (need x86_64 or aarch64)." "$RED"; exit 1 ;;
    esac
    influx_deb="/tmp/influxdb_${INFLUXDB_VERSION}_${influx_deb_arch}.deb"
    wget -q -O "$influx_deb" \
        "https://repos.influxdata.com/debian/packages/influxdb_${INFLUXDB_VERSION}_${influx_deb_arch}.deb" \
        || exit 1

    install -d /etc/apt/preferences.d
    printf 'Package: influxdb\nPin: version %s\nPin-Priority: 1001\n' "$INFLUXDB_VERSION" \
        > /etc/apt/preferences.d/10-fusion-influxdb

    apt-get update -y
    apt install $shared_pkgs $pkgs -y || exit 1
    apt install -y "$influx_deb" || exit 1
    rm -f "$influx_deb"
}

prereqs_el() {
    pkgs="httpd php-mysqlnd cronie mod_ssl"

    enable_el_repos

    # InfluxDB OSS v1 repo ($releasever and $basearch expanded by dnf/yum)
    if [ ! -f /etc/yum.repos.d/influxdb.repo ]; then
        cat <<'INFLUXREPO' > /etc/yum.repos.d/influxdb.repo
[influxdb]
name = InfluxDB Repository - RHEL $releasever
baseurl = https://repos.influxdata.com/rhel/$releasever/$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdata-archive.key
INFLUXREPO
    fi
    pkgs="$pkgs influxdb-$INFLUXDB_VERSION supervisor"

    if [ "$dist" == "el10" ]; then
        pkgs="$pkgs mysql8.4-server"
    else
        dnf module enable php:8.2 -y
        pkgs="$pkgs mysql-server"
    fi

    dnf install $shared_pkgs $pkgs -y
}

environment() {
    echo_c "Setting up the environment..." "$BLUE"

    if [ -f "$ETC_DIR/env" ]; then
        echo_c "Environment file already exists, skipping..." "$BLUE"
        return 1
    fi

    mkdir -p "$ETC_DIR/certs"

    export APP
    export APP_URL="http://localhost"
    export IP_ADDRESS
    export LIB_DIR
    export APP_UUID=$(uuidgen)
    export ROOT_MYSQL_PASS="$(generate_random_password)"

    if [ -z "$APP_MYSQL_PASS" ]; then
        APP_MYSQL_PASS="$(generate_random_password)"
    fi

    if [ -z "$APP_INFLUXDB_PASS" ]; then
        APP_INFLUXDB_PASS="$(generate_random_password)"
    fi

    export APP_MYSQL_PASS
    export APP_INFLUXDB_PASS

    export REVERB_APP_KEY="$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32)"
    export REVERB_APP_SECRET="$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32)"
    export REVERB_HOST="localhost"
    export REVERB_PORT=8080
    export REVERB_SCHEME=http

    if [[ "$distro" == "ubuntu" || "$distro" == "debian" ]]; then
        export LDAP_TRUST_STORE_ADD_CMD="sudo cp {file} /usr/local/share/ca-certificates/{basename} && sudo update-ca-certificates"
        export LDAP_TRUST_STORE_REMOVE_CMD="sudo rm -f /usr/local/share/ca-certificates/{basename} && sudo update-ca-certificates"
    else
        export LDAP_TRUST_STORE_ADD_CMD="sudo trust anchor --store {file}"
        export LDAP_TRUST_STORE_REMOVE_CMD="sudo trust anchor --remove {file}"
    fi

    echo_c "The MySQL root password will be: $ROOT_MYSQL_PASS" "$ORANGE"
    echo_c "The MySQL $APP password will be: $APP_MYSQL_PASS" "$ORANGE"
    echo_c "The InfluxDB $APP password will be: $APP_INFLUXDB_PASS" "$ORANGE"

    mkdir -p "$ETC_DIR"
    envsubst < "$INSTALL_PATH/.env.example" > "$ETC_DIR/env"
}

application() {
    echo_c "Copying application files..." "$BLUE"
    mkdir -p "$PROD_DIR"
    cp -r "$INSTALL_PATH/fusion/." "$PROD_DIR/"

    mkdir -p "$BACKEND_DIR"

    if [ -f "$ETC_DIR/env" ]; then
        ln -s "$ETC_DIR/env" "$PROD_DIR/.env"
    else
        echo_c "Environment file missing from $ETC_DIR, exiting..."
        exit 1
    fi
}

cron() {
    # Make sure cron is enabled and started
    if [[ "$distro" == "ubuntu" || "$distro" == "debian" ]]; then
        systemctl enable --now cron
    else
        systemctl enable --now crond
    fi

    # Create cron job for Laravel scheduler
    echo_c "Creating cron job for Laravel scheduler..." "$BLUE"
    CRON_JOB="* * * * * fusion cd $PROD_DIR && /usr/bin/php artisan schedule:run >> $PROD_DIR/storage/logs/cron.log 2>&1"
    echo "$CRON_JOB" > /etc/cron.d/fusion
    chmod 644 /etc/cron.d/fusion
    echo "Crontab for fusion set to: $CRON_JOB"
}

db() {
    echo_c "Setting up the MySQL database..." "$BLUE"

    echo "Starting mysqld..."
    systemctl start $mysqld
    systemctl enable $mysqld

    local root_mysql_pass=$(read_env_password "$ETC_DIR/env" "DB_ROOT_PASSWORD")
    if [ -z "$root_mysql_pass" ]; then
        echo_c "ERROR: No DB_ROOT_PASSWORD found in $ETC_DIR/env" "$RED"
        exit 1
    fi

    local app_mysql_pass=$(read_env_password "$ETC_DIR/env" "DB_PASSWORD")
    if [ -z "$app_mysql_pass" ]; then
        echo_c "ERROR: No DB_PASSWORD found in $ETC_DIR/env" "$RED"
        exit 1
    fi

    local root_mysql_pass_esc=$(escape_password "$root_mysql_pass")
    local app_mysql_pass_esc=$(escape_password "$app_mysql_pass")

    local db_exists=$(mysql -sse "SHOW DATABASES LIKE '$APP'")
    if [ "$db_exists" != "$APP" ]; then
        mysql -e "CREATE DATABASE $APP CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
        echo "Created MySQL database '$APP'."
    else
        echo_c "Database '$APP' already exists." "$ORANGE"
    fi

    local user_exists=$(mysql -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$APP' AND host = 'localhost')")
    if [ "$user_exists" -eq 0 ]; then
        mysql -e "CREATE USER '$APP'@'localhost' IDENTIFIED BY '${app_mysql_pass_esc}';"
        echo "Created MySQL user '$APP'@'localhost'."
    else
        echo_c "User '$APP'@'localhost' already exists." "$ORANGE"
        mysql -e "ALTER USER '$APP'@'localhost' IDENTIFIED BY '${app_mysql_pass_esc}';"
        if mysqlshow -u $APP &>/dev/null; then
            echo "Updated MySQL user '$APP'@'localhost' password."
        else
            echo_c "ERROR: Failed to verify updated password for '$APP'@'localhost'." "$RED"
            exit 1
        fi
    fi

    mysql -e "GRANT ALL PRIVILEGES ON $APP.* TO '$APP'@'localhost';"
    mysql -e "GRANT PROCESS, SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON *.* TO '$APP'@'localhost';"

    # set mysql root password and flush privileges :)
    mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${root_mysql_pass_esc}'; FLUSH PRIVILEGES;"
}

influxdb() {
    echo_c "Setting up InfluxDB OSS v1..." "$BLUE"

    local influxdb_conf="/etc/influxdb/influxdb.conf"
    local influx_user influx_pass influx_pass_esc
    local user_exists db_exists rp_exists
    local auth_ready="no"

    influx_user=$(read_env_password "$ETC_DIR/env" "INFLUXDB_USERNAME")
    influx_user=${influx_user:-$APP}
    influx_pass=$(read_env_password "$ETC_DIR/env" "INFLUXDB_PASSWORD")
    if [ -z "$influx_pass" ]; then
        echo_c "ERROR: No INFLUXDB_PASSWORD found in $ETC_DIR/env" "$RED"
        exit 1
    fi
    influx_pass_esc=$(escape_password "$influx_pass")

    if systemctl is-active --quiet influxdb 2>/dev/null; then
        echo_c "InfluxDB service already running." "$ORANGE"
    else
        echo "Starting influxdb..."
        systemctl start influxdb 2>/dev/null || service influxdb start
        systemctl enable influxdb 2>/dev/null || true
    fi

    # Prefer authenticated admin; fall back to unauthenticated (auth not yet enabled)
    if influx -username "$influx_user" -password "$influx_pass" -execute "SHOW USERS" &>/dev/null; then
        echo_c "InfluxDB user '$influx_user' already exists and password is valid." "$ORANGE"
        auth_ready="yes"
        influx -username "$influx_user" -password "$influx_pass" \
            -execute "GRANT ALL PRIVILEGES TO $influx_user" 2>/dev/null || true
    elif influx -execute "SHOW DATABASES" &>/dev/null; then
        auth_ready="no"
    else
        echo_c "ERROR: Could not connect to InfluxDB!" "$RED"
        exit 1
    fi

    influx_admin() {
        if [ "$auth_ready" = "yes" ]; then
            influx -username "$influx_user" -password "$influx_pass" -execute "$1"
        else
            influx -execute "$1"
        fi
    }

    echo "Testing InfluxDB connection..."
    if ! influx_admin "SHOW DATABASES" &>/dev/null; then
        echo_c "ERROR: Failed to connect to InfluxDB." "$RED"
        exit 1
    fi

    db_exists=$(influx_admin "SHOW DATABASES" | grep -w "$APP" || true)
    if [ -z "$db_exists" ]; then
        influx_admin "CREATE DATABASE $APP"
        echo "Created InfluxDB database '$APP'."
    else
        echo_c "InfluxDB database '$APP' already exists." "$ORANGE"
    fi

    user_exists=$(influx_admin "SHOW USERS" | grep -w "$influx_user" || true)
    if [ -z "$user_exists" ]; then
        influx_admin "CREATE USER $influx_user WITH PASSWORD '$influx_pass_esc' WITH ALL PRIVILEGES"
        echo "Created InfluxDB user '$influx_user'."
    else
        echo_c "InfluxDB user '$influx_user' already exists." "$ORANGE"
        influx_admin "SET PASSWORD FOR $influx_user = '$influx_pass_esc'"
        echo "Updated InfluxDB user '$influx_user' password."
    fi
    auth_ready="yes"

    echo_c "Setting up retention policies..." "$BLUE"

    rp_exists=$(influx_admin "SHOW RETENTION POLICIES ON \"$APP\"" | grep -w "24h" || true)
    if [ -z "$rp_exists" ]; then
        influx_admin "CREATE RETENTION POLICY \"24h\" ON \"$APP\" DURATION 24h REPLICATION 1"
        echo "Created retention policy '24h'."
    else
        echo_c "Retention policy '24h' already exists." "$ORANGE"
    fi

    rp_exists=$(influx_admin "SHOW RETENTION POLICIES ON \"$APP\"" | grep -w "30d" || true)
    if [ -z "$rp_exists" ]; then
        influx_admin "CREATE RETENTION POLICY \"30d\" ON \"$APP\" DURATION 30d REPLICATION 1"
        echo "Created retention policy '30d'."
    else
        echo_c "Retention policy '30d' already exists." "$ORANGE"
    fi

    # Enable authentication last (NNA sed)
    echo_c "Enabling authentication..." "$BLUE"
    if [ -f "$influxdb_conf" ]; then
        if grep -q "auth-enabled = true" "$influxdb_conf"; then
            echo_c "InfluxDB authentication already enabled." "$ORANGE"
        else
            echo "Enabling InfluxDB authentication..."
            if grep -q "# auth-enabled = false" "$influxdb_conf"; then
                sed -i 's/# auth-enabled = false/auth-enabled = true/' "$influxdb_conf"
            elif grep -q "auth-enabled = false" "$influxdb_conf"; then
                sed -i 's/auth-enabled = false/auth-enabled = true/' "$influxdb_conf"
            else
                sed -i '/^\[http\]/a\  auth-enabled = true' "$influxdb_conf"
            fi
            systemctl restart influxdb 2>/dev/null || service influxdb restart
            echo "InfluxDB authentication enabled and service restarted."
            sleep 3
        fi
    fi

    if influx_admin "SHOW DATABASES" | grep -q "$APP"; then
        echo "Verified InfluxDB user '$influx_user' can connect."
    else
        echo_c "ERROR: Failed to verify InfluxDB user '$influx_user' connection." "$RED"
        exit 1
    fi

    echo_c "InfluxDB configuration complete!" "$GREEN"
}

artisan() {
    cd "$PROD_DIR" && php artisan key:generate

    # Run migrations
    echo_c "Running database migrations..." "$BLUE"
    cd "$PROD_DIR" && php artisan migrate --force

    echo_c "Running database seeders..." "$BLUE"
    cd "$PROD_DIR" && php artisan db:seed
}

fusion_supervisor() {
    echo_c "Setting up Supervisor (queue, Reverb)..." "$BLUE"

    LOG_FILE_DIR="$PROD_DIR/storage/logs"
    if [[ "$distro" == "ubuntu" || "$distro" == "debian" ]]; then
        SUPERVISOR_SERVICE="supervisor"
        SUPERVISOR_FUSION_FILE="/etc/supervisor/conf.d/fusion.conf"
    else
        SUPERVISOR_SERVICE="supervisord"
        SUPERVISOR_FUSION_FILE="/etc/supervisord.d/fusion.ini"
    fi

    install -d -o root -g root "$LOG_FILE_DIR"

    # Set default permissions for the logs directory, so group members can write to it
    setfacl -d -m u::rw-,g::rw-,o::r-- "$LOG_FILE_DIR"

    export PROD_DIR APP LOG_FILE_DIR
    envsubst < "$INSTALL_PATH/fusion-supervisor.conf" > "$SUPERVISOR_FUSION_FILE"

    if ! pgrep -x "$SUPERVISOR_SERVICE" > /dev/null; then
        echo "Starting Supervisor..."
        systemctl enable $SUPERVISOR_SERVICE
        systemctl start $SUPERVISOR_SERVICE
    else
        echo_c "Supervisor is already running. Restarting..." "$ORANGE"
        supervisorctl stop all
        systemctl restart $SUPERVISOR_SERVICE
    fi

    echo "Reloading Supervisor config..."
    supervisorctl reread
    supervisorctl update

    echo "Starting Supervisor processes..."
    supervisorctl start all
    sleep 2
    status_output=$(supervisorctl status)

    if echo "$status_output" | grep -q "^fusion-reverb.*RUNNING"; then
        echo "fusion-reverb is running."
    else
        echo_c "ERROR: fusion-reverb is not running" "$RED"
        exit 1
    fi

    worker_count="$(echo "$status_output" | grep -E "^fusion-queue:fusion-queue_[0-9]+" | wc -l)"
    running_worker_count="$(echo "$status_output" | grep -E "^fusion-queue:fusion-queue_[0-9]+.*RUNNING" | wc -l)"
    if [ "$worker_count" -eq "$running_worker_count" ]; then
        echo "All $running_worker_count fusion-queue processes are running."
    else
        echo_c "ERROR: Some fusion-queue processes are not running" "$RED"
        echo "$status_output" | grep "^fusion-queue"
        exit 1
    fi

    echo "Supervisor setup completed!"
}

firewall() {
    if [[ "$dist" == el* ]]; then
        # Opens default Apache ports and default fusion-collector port
        open_ports 80 443 8080 9000
    fi
}

selinux() {
    # Disable SELinux if it's enabled. This should be done on EL systems.
    if [[ "$dist" == el* ]]; then
        disable_selinux
        semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/fusion/storage(/.*)?"
        semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/fusion/bootstrap/cache(/.*)?"
        restorecon -Rv /var/www/html/fusion/storage
        restorecon -Rv /var/www/html/fusion/bootstrap/cache
        setsebool -P httpd_can_network_connect_db 1
    fi
}

apache() {
    echo_c "Creating Apache config file..." "$BLUE"

    cp "$INSTALL_PATH/$APP.conf" "$httpdconfdir"
    echo "    ErrorLog /var/log/$httpd/laravel-error.log" >> "$httpdconfdir/$APP.conf"
    echo "    CustomLog /var/log/$httpd/laravel-access.log combined" >> "$httpdconfdir/$APP.conf"
    echo "</VirtualHost>" >> "$httpdconfdir/$APP.conf"

    if [[ "$distro" == "ubuntu" || "$distro" == "debian" ]]; then
        a2enmod ssl
        a2enmod rewrite
        a2ensite default-ssl

        # Remove the default configuration
        a2dissite 000-default.conf
        a2ensite "$APP".conf
    fi

    sed -i "s|^\s*ServerName .*|    ServerName localhost|" "${httpdconfdir}/$APP.conf"

    echo_c "Setting up Apache..." "$BLUE"
    php_fpm_service=""
    if [[ "$distro" == "ubuntu" || "$distro" == "debian" ]]; then
        php_version=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
        php_fpm_service="php${php_version}-fpm"
    else
        php_fpm_service="php-fpm"
    fi

    echo_c "Configuring php.ini..." "$BLUE"
    PHP_MEMORY_LIMIT="2G"
    PHP_POST_MAX_SIZE="1200M"
    PHP_UPLOAD_MAX_FILESIZE="1G"

    if [[ "$distro" == "ubuntu" || "$distro" == "debian" ]]; then
        for ini in $phpini $phpcliini $phpfpmini; do
            set_php_ini "$ini" "memory_limit" "$PHP_MEMORY_LIMIT"
            set_php_ini "$ini" "post_max_size" "$PHP_POST_MAX_SIZE"
            set_php_ini "$ini" "upload_max_filesize" "$PHP_UPLOAD_MAX_FILESIZE"
        done
    else
        set_php_ini "$phpini" "memory_limit" "$PHP_MEMORY_LIMIT"
        set_php_ini "$phpini" "post_max_size" "$PHP_POST_MAX_SIZE"
        set_php_ini "$phpini" "upload_max_filesize" "$PHP_UPLOAD_MAX_FILESIZE"
    fi

    echo_c "Restarting $httpd..." "$BLUE"
    systemctl enable --now "$php_fpm_service"
    systemctl enable $httpd
    systemctl restart "$httpd"
}

directories() {
    echo_c "Creating directories..." "$BLUE"
    mkdir -p "$LIB_DIR/cacerts"
}

scripts() {
    echo_c "Creating scripts directory..." "$BLUE"
    mkdir -p "$BACKEND_DIR/scripts"
    cp -a "$INSTALL_PATH/scripts/." "$BACKEND_DIR/scripts/"
}

permissions() {
    # Adding the apacheuser to the APP group
    add_to_groups "$apacheuser" "$nagiosgroup"

    # App permissions
    chown -R "$APP:$APP" "$PROD_DIR"
    find "$PROD_DIR" -type f -exec chmod 664 {} +
    find "$PROD_DIR" -type d -exec chmod 775 {} +

    # Environment file permissions
    chmod 640 "$PROD_DIR/.env"
    chown "$APP":"$apachegroup" "$PROD_DIR/.env"

    # Laravel storage/cache permissions
    chown -R "$APP":$apachegroup "$PROD_DIR/storage" "$PROD_DIR/bootstrap/cache"
    chmod -R 0775 "$PROD_DIR/storage"
    chmod -R 0775 "$PROD_DIR/bootstrap/cache"

    # Permissions for the logs directory with setgid to force group for Laravel logs
    chown -R "$nagiosuser":$nagiosgroup "$LOG_FILE_DIR"
    chmod g+s "$LOG_FILE_DIR"

    # CA cert permissions
    chown -R "$APP:$apachegroup" "$LIB_DIR/cacerts"
    chmod -R 0775 "$LIB_DIR/cacerts"

    # Allow the PHP-FPM user to manage system trust store via sudo.
    # PHP-FPM runs as $apacheuser (apache on RHEL, www-data on Debian/Ubuntu),
    # so the NOPASSWD rules must target that user.
    local sudoers_file="/etc/sudoers.d/$APP-trust"
    if [[ "$distro" == "ubuntu" || "$distro" == "debian" ]]; then
        cat > "$sudoers_file" <<SUDOERS
$apacheuser ALL=(root) NOPASSWD: /usr/bin/cp * /usr/local/share/ca-certificates/*
$apacheuser ALL=(root) NOPASSWD: /usr/bin/rm -f /usr/local/share/ca-certificates/*
$apacheuser ALL=(root) NOPASSWD: /usr/sbin/update-ca-certificates
SUDOERS
    else
        cat > "$sudoers_file" <<SUDOERS
$apacheuser ALL=(root) NOPASSWD: /usr/bin/trust anchor --store *
$apacheuser ALL=(root) NOPASSWD: /usr/bin/trust anchor --remove *
SUDOERS
    fi
    chmod 0440 "$sudoers_file"

    # System status collectors (mpstat via sysstat) and queue worker management.
    local supervisor_sudoers="/etc/sudoers.d/$APP-supervisor"
    cat > "$supervisor_sudoers" <<SUDOERS
$apacheuser ALL=(root) NOPASSWD: /usr/bin/supervisorctl status
$apacheuser ALL=(root) NOPASSWD: /usr/bin/supervisorctl restart *
$APP ALL=(root) NOPASSWD: /usr/bin/supervisorctl status
$APP ALL=(root) NOPASSWD: /usr/bin/supervisorctl restart *
SUDOERS
    chmod 0440 "$supervisor_sudoers"

    local collector_sudoers="/etc/sudoers.d/$APP-collector"
    cat > "$collector_sudoers" <<SUDOERS
$apacheuser ALL=(root) NOPASSWD: /usr/bin/systemctl status fusion-collector
$apacheuser ALL=(root) NOPASSWD: /usr/bin/systemctl is-active fusion-collector
$apacheuser ALL=(root) NOPASSWD: /usr/bin/systemctl show fusion-collector *
$apacheuser ALL=(root) NOPASSWD: /usr/bin/systemctl start fusion-collector
$apacheuser ALL=(root) NOPASSWD: /usr/bin/systemctl stop fusion-collector
$apacheuser ALL=(root) NOPASSWD: /usr/bin/systemctl restart fusion-collector
$apacheuser ALL=(root) NOPASSWD: /usr/bin/systemctl enable fusion-collector
$apacheuser ALL=(root) NOPASSWD: /usr/bin/systemctl disable fusion-collector
$apacheuser ALL=(root) NOPASSWD: /usr/sbin/ss *, /usr/bin/ss *
$APP ALL=(root) NOPASSWD: /usr/bin/systemctl status fusion-collector
$APP ALL=(root) NOPASSWD: /usr/bin/systemctl is-active fusion-collector
$APP ALL=(root) NOPASSWD: /usr/bin/systemctl show fusion-collector *
$APP ALL=(root) NOPASSWD: /usr/bin/systemctl start fusion-collector
$APP ALL=(root) NOPASSWD: /usr/bin/systemctl stop fusion-collector
$APP ALL=(root) NOPASSWD: /usr/bin/systemctl restart fusion-collector
$APP ALL=(root) NOPASSWD: /usr/bin/systemctl enable fusion-collector
$APP ALL=(root) NOPASSWD: /usr/bin/systemctl disable fusion-collector
$APP ALL=(root) NOPASSWD: /usr/sbin/ss *, /usr/bin/ss *
SUDOERS
    chmod 0440 "$collector_sudoers"
}

fusion_collector() {
    echo_c "Setting up Fusion Collector..." "$BLUE"

    mkdir -p "/var/log/fusion-collector"
    chown -R "$APP:$APP" "/var/log/fusion-collector"
    chmod -R 0775 "/var/log/fusion-collector"

    # Install the collector binary
    install -m 0755 "$INSTALL_PATH/subcomponents/fusion-collector/fusion-collector" "/usr/local/bin/fusion-collector"

    # Create the collector configuration file
    cat > "/etc/fusion/collector.toml" <<CONFIG
[server]
host = "0.0.0.0"
port = 9000
log_dir = "/var/log/fusion-collector"
log_level = "info"  # error|warn|info|debug

# Optional — omit this section for plaintext TCP.
# [tls]
# cert_file = "/etc/fusion/certs/collector.pem"
# key_file = "/etc/fusion/certs/collector.key"

[mysql]
url = "mysql://$APP:$APP_MYSQL_PASS@127.0.0.1:3306/$APP"

[influxdb]
url = "http://localhost:8086"
database = "$APP"
retention_policy = "30d"
batch_size = 25
flush_interval_ms = 2000
username = "$APP"
password = "$APP_INFLUXDB_PASS"

CONFIG
    chown "$APP:$apachegroup" "/etc/fusion/collector.toml"
    chmod 660 "/etc/fusion/collector.toml"

    # Create the collector service file
    cat > "/etc/systemd/system/fusion-collector.service" <<SERVICE
[Unit]
Description=Fusion EDA Broker
After=network-online.target

[Service]
User=fusion
Group=fusion
ExecStart=/usr/local/bin/fusion-collector
Restart=on-failure

[Install]
WantedBy=multi-user.target

SERVICE

    # Size-based rotation (copytruncate: collector keeps open FDs; SIGHUP reloads servers)
    cat > "/etc/logrotate.d/fusion-collector" <<LOGROTATE
/var/log/fusion-collector/ops.log {
    size 10M
    rotate 5
    missingok
    notifempty
    compress
    delaycompress
    copytruncate
    create 0664 $APP $APP
}

/var/log/fusion-collector/events.log {
    size 100M
    rotate 5
    missingok
    notifempty
    compress
    delaycompress
    copytruncate
    create 0664 $APP $APP
}
LOGROTATE
    chmod 0644 "/etc/logrotate.d/fusion-collector"

    # Install unit but leave disabled; start via UI or systemctl when needed
    systemctl daemon-reload
    systemctl disable fusion-collector
    systemctl stop fusion-collector 2>/dev/null || true

    echo "Fusion Collector setup completed (service installed but not started)!"
}

##############################
### START THE INSTALLATION ###
##############################

fullinstall() {
    while [ -n "$1" ]; do
        case "$1" in
            -h | --help )
                install_help
                exit 0
                ;;
            -f | --force )
                FORCE="True"
                ;;
            -n | --non-interactive )
                INTERACTIVE="False"
                ;;
            * )
                echo "Unknown option:  $1" >&2
                usage_install >&2
                exit 1
        esac
        shift
    done

    print_header "Nagios $APP_NAME"

    # Verify that the app is not already installed
    if [ -f "$INSTALLED_FLAG" ]; then
        if [ "$FORCE" = "True" ]; then
            echo_c "Forcing re-install..." "$BLUE"

            echo "Removing existing installation..."
            rm -rf "$PROD_DIR"
            rm -rf "$BACKEND_DIR"
            rm -f "$INSTALL_PATH"/installed*
            rm -f "$INSTALL_PATH/install.log"
            rm -f "$INSTALLED_FLAG"
        else
            echo_c "ERROR: It looks like Nagios $APP_NAME is already installed!" "$RED"
            echo_c "If you know what you're doing, you can run the installer with -f / --force to force the installation." "$RED"
            exit 1
        fi
    fi

    if [ "$INTERACTIVE" = "True" ]; then
        echo
        echo_c "Enter a password to use for the MySQL $APP user. It must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, and one digit. A random password will be chosen if one is not entered..." "$GREEN"
        prompt_for_password APP_MYSQL_PASS
        echo
        echo_c "Enter a password to use for the InfluxDB $APP user (same rules). A random password will be chosen if one is not entered..." "$GREEN"
        prompt_for_password APP_INFLUXDB_PASS
        echo
    fi

    if ! path_is_ok; then
        echo "Your system \$PATH does not include /sbin and /usr/sbin."
        echo "Adding /sbin and /usr/sbin to \$PATH."
        PATH="$PATH:/usr/sbin:/sbin"
    fi

    run_steps prereqs environment create_users application install_sourceguardian db influxdb artisan fusion_supervisor firewall directories scripts permissions selinux apache cron fusion_collector

    trap - 0

    touch "$INSTALLED_FLAG"

    URL="http://$IP_ADDRESS/install"
    URL_LENGTH=${#URL}
    PADDING=$((45 - URL_LENGTH))

    echo
    echo_c "######################################################" "$CYAN"
    echo_c "#                                                    #" "$CYAN"
    echo_c "#   Nagios $APP_NAME Installation Complete!             #" "$CYAN"
    echo_c "#                                                    #" "$CYAN"
    echo_c "# -------------------------------------------------- #" "$CYAN"
    echo_c "#                                                    #" "$CYAN"
    echo_c "#   Complete the final setup steps by visiting:      #" "$CYAN"
    printf "${CYAN}#${NC}       ${BLUE}%s${NC}%*s${CYAN}#${NC}\n" "$URL" "$PADDING" ""
    echo_c "#                                                    #" "$CYAN"
    echo_c "######################################################" "$CYAN"
    echo
}

log_it install.log fullinstall "$@"