#!/bin/bash
set -euo pipefail

usage() {
  echo "Usage: $0 --controller URL --agent-id ID --enrollment-token TOKEN"
}

controller=""
agent_id=""
enrollment_token=""

while [ "$#" -gt 0 ]; do
  case "$1" in
    --controller) controller="${2:-}"; shift 2 ;;
    --agent-id) agent_id="${2:-}"; shift 2 ;;
    --enrollment-token) enrollment_token="${2:-}"; shift 2 ;;
    *) usage; exit 64 ;;
  esac
done

if [ "$(id -u)" -ne 0 ]; then
  echo "Run this installer as root" >&2
  exit 77
fi
if [[ ! "$controller" =~ ^https:// ]] ||
   [[ ! "$agent_id" =~ ^[A-Za-z0-9_.-]{3,80}$ ]] ||
   [ -z "$enrollment_token" ]; then
  usage
  exit 64
fi

workdir="$(mktemp -d)"
trap 'rm -rf "$workdir"' EXIT
bundle_name="modguard-agent.tar.gz"
checksum_name="${bundle_name}.sha256"
curl -fsS "$controller/downloads/$bundle_name" -o "$workdir/$bundle_name"
curl -fsS "$controller/downloads/$checksum_name" -o "$workdir/$checksum_name"
(
  cd "$workdir"
  sha256sum -c "$checksum_name"
)

release="$(date -u +%Y%m%dT%H%M%SZ)"
install_root="/opt/modem-guardian"
release_dir="$install_root/releases/$release"
install -d -m 0755 "$release_dir" /etc/modem-guardian /var/lib/modem-guardian
tar -xzf "$workdir/$bundle_name" -C "$release_dir"

existing_config="/etc/modem-guardian/agent.json"
if [ -f "$existing_config" ]; then
  existing_agent_id="$(
    python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["agent_id"])' \
      "$existing_config"
  )"
  if [ "$existing_agent_id" != "$agent_id" ]; then
    echo "Existing agent_id $existing_agent_id does not match $agent_id" >&2
    exit 65
  fi
  cp -a "$existing_config" "$existing_config.pre-update-$release"
  if [ -f /etc/modem-guardian/controller.token ]; then
    mv /etc/modem-guardian/controller.token \
      "/etc/modem-guardian/controller.token.pre-update-$release"
  fi
  python3 -c '
import json, sys
path, controller = sys.argv[1:3]
with open(path, encoding="utf-8") as source:
    payload = json.load(source)
payload["controller_url"] = controller.rstrip("/")
payload["controller_token_file"] = "/etc/modem-guardian/controller.token"
payload["enrollment_token_file"] = "/etc/modem-guardian/enrollment.token"
payload["inventory_config_glob"] = "/etc/3proxy/modem-id-*.cfg"
payload.setdefault("keenetic_username", "admin")
payload.setdefault("proxy_listener_reconcile_enabled", True)
payload.setdefault("proxy_listener_reconcile_interval", 60)
payload.setdefault("proxy_listener_reconcile_batch_size", 2)
if payload.get("router_password_file"):
    payload.setdefault(
        "keenetic_password_file",
        payload["router_password_file"],
    )
payload.pop("kraken_api_base", None)
payload.pop("kraken_token_file", None)
with open(path, "w", encoding="utf-8") as target:
    json.dump(payload, target, ensure_ascii=True, indent=2)
    target.write("\n")
' "$existing_config" "$controller"
  install_mode="updated"
else
  read -r -s -p "Router management password (leave empty for monitor-only): " router_password
  echo
  if [ -n "$router_password" ]; then
    printf '%s\n' "$router_password" > /etc/modem-guardian/router.password
    chmod 0600 /etc/modem-guardian/router.password
  fi
  install_mode="installed"
fi

printf '%s\n' "$enrollment_token" > /etc/modem-guardian/enrollment.token
chmod 0600 /etc/modem-guardian/enrollment.token

if [ ! -f "$existing_config" ]; then
  cat > "$existing_config" <<EOF
{
  "agent_id": "$agent_id",
  "inventory_config_glob": "/etc/3proxy/modem-id-*.cfg",
  "controller_url": "$controller",
  "controller_token_file": "/etc/modem-guardian/controller.token",
  "enrollment_token_file": "/etc/modem-guardian/enrollment.token",
  "spool_path": "/var/lib/modem-guardian/spool.sqlite",
  "poll_interval": 30,
  "jitter": 5,
  "mode": "discovery",
  "monitor_allowlist": ["*"],
  "non_customer_proxy_logins": ["rooot"],
  "rented_proxy_ports": [],
  "max_probe_workers": 4,
  "identity_refresh_seconds": 86400,
  "identity_refresh_batch": 16,
  "sms_enabled": false,
  "sms_allowlist": [],
  "sms_poll_interval": 900,
  "sms_poll_batch": 4,
  "sms_auto_delete_enabled": false,
  "sms_auto_delete_allowlist": [],
  "sms_auto_delete_ack": "",
  "router_password_file": "/etc/modem-guardian/router.password",
  "keenetic_username": "admin",
  "keenetic_password_file": "/etc/modem-guardian/router.password",
  "ip_rotation_enabled": false,
  "ip_rotation_allowlist": [],
  "ip_rotation_ack": "",
  "ip_checkers": [
    {"name": "modguard", "url": "$controller/probe/ip?nonce={nonce}", "ip_field": "ip", "nonce_required": "true"},
    {"name": "cloudflare", "url": "https://1.1.1.1/cdn-cgi/trace"}
  ],
  "regional_ip_checkers": [
    {"name": "yandex-internetometer", "url": "https://yandex.ru/internet/api/v0/ip?nonce={nonce}"},
    {"name": "yandex-internetometer-fallback", "url": "https://yandex.com/internet/api/v0/ip?nonce={nonce}"}
  ],
  "russian_canaries": [
    {"name": "yandex", "url": "https://yandex.ru/robots.txt"},
    {"name": "vk", "url": "https://vk.com/robots.txt"},
    {"name": "ok", "url": "https://ok.ru/robots.txt"}
  ],
  "captive_portal_url": "http://example.com/",
  "captive_portal_reboot_enabled": false,
  "captive_portal_reboot_allowlist": [],
  "captive_portal_reboot_ack": "",
  "captive_portal_reboot_interval": 1800,
  "recovery_enabled": false,
  "controller_managed_recovery": true,
  "proxy_listener_reconcile_enabled": true,
  "proxy_listener_reconcile_interval": 60,
  "proxy_listener_reconcile_batch_size": 2,
  "recovery_allowlist": [],
  "recovery_ack": ""
}
EOF
fi

chmod 0640 "$existing_config"
ln -sfn "$release_dir" "$install_root/current"
install -m 0644 "$release_dir/deploy/modem-guardian-agent.service" \
  /etc/systemd/system/modem-guardian-agent.service
install -m 0644 \
  "$release_dir/deploy/sysctl/70-modguard-proxy-ports.conf" \
  /etc/sysctl.d/70-modguard-proxy-ports.conf
sysctl --system >/dev/null
systemctl daemon-reload
systemctl enable modem-guardian-agent.service
systemctl restart modem-guardian-agent.service
sleep 3
systemctl --no-pager --full status modem-guardian-agent.service
echo "ModGuard agent $agent_id $install_mode and enrolled."
