#!/usr/bin/env bash
# barox Virtual Switch Simulator — installer for Ubuntu Server 24.04 LTS.
# No Composer, no PHP framework. Installs Apache2 + PHP + MySQL/MariaDB
# system packages, creates the database, imports schema+seed, writes
# config/local.php, installs the Apache vhost and the three systemd
# worker services, then starts everything.
#
# Usage: sudo scripts/install.sh
# Optional environment overrides: DB_NAME, DB_USER, DB_PASSWORD, APP_URL
set -euo pipefail

APP_DIR="/var/www/html/barox-swtsim"
LOG_DIR="/var/log/barox-switch-simulator"
DB_NAME="${DB_NAME:-barox_switch_sim}"
DB_USER="${DB_USER:-barox_sim}"
DB_PASSWORD="${DB_PASSWORD:-$(php -r 'echo bin2hex(random_bytes(16));')}"
APP_URL="${APP_URL:-http://localhost}"
APP_SECRET="$(php -r 'echo bin2hex(random_bytes(32));')"

if [ "$(id -u)" -ne 0 ]; then
    echo "This script must be run as root: sudo scripts/install.sh" >&2
    exit 1
fi

echo "==> Installing system packages (apt)..."
export DEBIAN_FRONTEND=noninteractive
apt-get update -y

# Only install a DB server package if none is already present. Installing
# mariadb-server alongside an already-installed, already-running mysql-server
# is NOT a harmless no-op: apt can resolve the conflict by REMOVING
# mysql-server entirely (this took down a shared production MySQL instance
# for several minutes on 2026-08-28). Detect first, always.
DB_SERVER_PACKAGE=""
if command -v mysql >/dev/null 2>&1 || command -v mariadb >/dev/null 2>&1 \
    || dpkg -s mysql-server >/dev/null 2>&1 || dpkg -s mariadb-server >/dev/null 2>&1; then
    echo "    Existing MySQL/MariaDB server detected — NOT installing a DB server package."
else
    DB_SERVER_PACKAGE="mariadb-server"
    echo "    No MySQL/MariaDB server detected — will install mariadb-server."
fi

apt-get install -y apache2 php php-cli php-mysql ${DB_SERVER_PACKAGE} snmp curl

if ! php -m | grep -qi '^sockets$'; then
    echo "WARNING: the PHP 'sockets' extension is not enabled. The SNMP agent"
    echo "(workers/snmp-agent.php) requires it. On most Ubuntu PHP builds it"
    echo "is compiled in by default; if missing, check your php.ini / install"
    echo "a php*-sockets package matching your PHP version." >&2
fi

echo "==> Enabling required Apache modules..."
a2enmod rewrite headers >/dev/null

echo "==> Ensuring MariaDB/MySQL is running..."
systemctl enable --now mariadb 2>/dev/null || systemctl enable --now mysql 2>/dev/null || true

# If config/local.php already exists, the database was already set up in a
# previous run (or manually, e.g. matching DB_NAME/DB_USER/DB_PASSWORD to an
# existing DB). Re-importing sql/seed.sql against an already-seeded database
# fails on the demo switch's UNIQUE management_ip and (with `set -e`) would
# abort the whole script before the Apache/systemd steps below ever run — so
# skip DB provisioning entirely rather than risk that.
if [ -f "${APP_DIR}/config/local.php" ]; then
    echo "==> config/local.php already exists — assuming the database is already"
    echo "    set up, skipping database creation and schema/seed import."
else
    echo "==> Creating database and user (if not already present)..."
    mysql --user=root <<SQL
CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'localhost';
FLUSH PRIVILEGES;
SQL

    echo "==> Importing schema and seed data..."
    mysql --user=root "${DB_NAME}" < "${APP_DIR}/sql/schema.sql"
    mysql --user=root "${DB_NAME}" < "${APP_DIR}/sql/seed.sql"
fi

echo "==> Writing config/local.php..."
if [ ! -f "${APP_DIR}/config/local.php" ]; then
    cat > "${APP_DIR}/config/local.php" <<PHP
<?php

declare(strict_types=1);

return [
    'db' => [
        'host'     => '127.0.0.1',
        'port'     => 3306,
        'name'     => '${DB_NAME}',
        'user'     => '${DB_USER}',
        'password' => '${DB_PASSWORD}',
        'charset'  => 'utf8mb4',
    ],
    'app' => [
        'url'      => '${APP_URL}',
        'secret'   => '${APP_SECRET}',
        'timezone' => 'Europe/Zurich',
        'env'      => 'production',
    ],
    'snmp' => [
        'default_port' => 161,
        'dev_port'     => 1161,
    ],
    'log_dir' => '${LOG_DIR}',
];
PHP
else
    echo "    config/local.php already exists — leaving it untouched."
fi

echo "==> Installing Apache vhost..."
cp "${APP_DIR}/apache/barox-switch-simulator.conf" /etc/apache2/sites-available/barox-switch-simulator.conf
a2ensite barox-switch-simulator >/dev/null
apache2ctl configtest
systemctl reload apache2

echo "==> Installing systemd services..."
cp "${APP_DIR}/systemd/barox-snmp.service" /etc/systemd/system/
cp "${APP_DIR}/systemd/barox-scenario.service" /etc/systemd/system/
cp "${APP_DIR}/systemd/barox-trap.service" /etc/systemd/system/
systemctl daemon-reload

echo "==> Setting permissions..."
bash "${APP_DIR}/scripts/permissions.sh"

echo "==> Enabling and starting services..."
systemctl enable --now barox-snmp.service
systemctl enable --now barox-scenario.service
systemctl enable --now barox-trap.service

cat <<EOF

============================================================================
 barox Virtual Switch Simulator — installation complete
============================================================================

 Web UI:        ${APP_URL}/
 Default login: admin / ChangeMe!2026   (CHANGE THIS IMMEDIATELY)

 Database:      ${DB_NAME} (user: ${DB_USER})
 Demo switch:    "Demo RY-LGSP38-28" on 127.0.0.1:1161 (SNMP, dev port)

 Test SNMP:
   snmpwalk -v2c -c public -p 1161 127.0.0.1

 Services:
   systemctl status barox-snmp barox-scenario barox-trap

 Logs:
   ${LOG_DIR}/{app,snmp,scenario,trap}.log

 To add more virtual switches with their own IPs, see docs/SNMP.md and
 docs/ARCHITECTURE.md §5 (ip addr add ..., then create the switch in the
 Web UI or via the REST API).

 Apache vhost: bound to ServerName swtsim.barox.io (not a wildcard catch-all)
 so it cannot shadow other sites' default routing on this shared host. Point
 DNS/your reverse proxy at this server for that hostname if you haven't.
============================================================================
EOF
