#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=/dev/null
source "$SCRIPT_DIR/libenv.sh"

ENV_FILE=$(limristem_mail_resolve_main_env_file)
BASE_DIR=${LIMRISTEM_MAIL_BASE_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}
WEBMAIL_DIR=/var/www/roundcube
STATE_FILE=$BASE_DIR/config/webmail.json
DEFAULT_ROUNDCUBE_VERSION="1.7.2"

fetch_latest_roundcube_version() {
  python3 -c "
import urllib.request, json, sys
try:
    req = urllib.request.Request('https://api.github.com/repos/roundcube/roundcubemail/releases/latest', headers={'User-Agent': 'Mozilla/5.0'})
    with urllib.request.urlopen(req, timeout=5) as resp:
        d = json.loads(resp.read())
        ver = d.get('tag_name', '').lstrip('v')
        if ver:
            print(ver)
            sys.exit(0)
except Exception:
    pass
print('1.7.2')
" 2>/dev/null || printf '1.7.2\n'
}

usage() {
  cat <<'EOF'
Usage:
  manage-webmail.sh status [--json]
  manage-webmail.sh install [--version <version>] [--json]
  manage-webmail.sh upgrade [--json]
  manage-webmail.sh set-auto-update <yes|no> [--json]
  manage-webmail.sh remove [--json]
EOF
}

load_env() {
  limristem_mail_load_env_file "$ENV_FILE"
}

require_root() {
  if [[ $EUID -ne 0 ]]; then
    echo "Run as root." >&2
    exit 1
  fi
}

json_flag() {
  if [[ "${1:-}" == "--json" || "${2:-}" == "--json" || "${3:-}" == "--json" ]]; then
    printf 'yes\n'
  else
    printf 'no\n'
  fi
}

detect_php_fpm_sock() {
  local sock
  for sock in /run/php/php*-fpm.sock /var/run/php/php*-fpm.sock /run/php/php-fpm.sock; do
    if [[ -S "$sock" ]]; then
      printf '%s\n' "$sock"
      return 0
    fi
  done
  printf '/run/php/php-fpm.sock\n'
}

detect_installed_version() {
  if [[ -f "$WEBMAIL_DIR/composer.json" ]]; then
    python3 -c "
import json
try:
    d = json.load(open('$WEBMAIL_DIR/composer.json'))
    print(d.get('version', '$DEFAULT_ROUNDCUBE_VERSION'))
except Exception:
    print('$DEFAULT_ROUNDCUBE_VERSION')
" 2>/dev/null || printf '%s\n' "$DEFAULT_ROUNDCUBE_VERSION"
  elif [[ -f "$STATE_FILE" ]]; then
    python3 -c "
import json
try:
    d = json.load(open('$STATE_FILE'))
    print(d.get('version', '$DEFAULT_ROUNDCUBE_VERSION'))
except Exception:
    print('$DEFAULT_ROUNDCUBE_VERSION')
" 2>/dev/null || printf '%s\n' "$DEFAULT_ROUNDCUBE_VERSION"
  else
    printf '%s\n' "$DEFAULT_ROUNDCUBE_VERSION"
  fi
}

get_status_json() {
  local installed="no" active="no" ver="" auto_update
  auto_update=${LIMRISTEM_MAIL_WEBMAIL_AUTO_UPDATE:-no}
  if [[ -f "$WEBMAIL_DIR/index.php" ]]; then
    installed="yes"
    ver=$(detect_installed_version)
    if systemctl is-active --quiet nginx && (systemctl is-active --quiet "php*-fpm" || systemctl is-active --quiet php8.4-fpm || systemctl is-active --quiet php8.2-fpm || systemctl is-active --quiet php-fpm); then
      active="yes"
    fi
  fi

  python3 - "$installed" "$active" "$ver" "$auto_update" <<'PY'
import json
import sys

installed = sys.argv[1] == "yes"
active = sys.argv[2] == "yes"
version = sys.argv[3]
auto_update = sys.argv[4]

print(json.dumps({
    "installed": installed,
    "active": active,
    "version": version if installed else None,
    "auto_update": auto_update,
    "url_mail": "/mail",
    "url_webmail": "/webmail",
    "webmail_dir": "/var/www/roundcube",
}))
PY
}

install_php_stack() {
  echo "[Webmail] Installing PHP-FPM and required webmail packages..." >&2
  export DEBIAN_FRONTEND=noninteractive
  apt-get update -qq || true
  apt-get install -y -qq php-fpm php-cli php-mysql php-xml php-mbstring php-intl php-zip php-gd php-curl php-imagick curl tar || true
  systemctl enable --now php*-fpm 2>/dev/null || true
}

ensure_mariadb_webmail_db() {
  local db_pass
  db_pass=$(limristem_mail_get_env_value "$ENV_FILE" "LIMRISTEM_MAIL_ROUNDCUBE_DB_PASS" || true)
  if [[ -z "$db_pass" ]]; then
    db_pass=$(openssl rand -hex 16)
    limristem_mail_upsert_env_value "$ENV_FILE" "LIMRISTEM_MAIL_ROUNDCUBE_DB_PASS" "$db_pass"
  fi

  mysql -e "CREATE DATABASE IF NOT EXISTS \`limristem_roundcube\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null || true
  mysql -e "GRANT ALL PRIVILEGES ON \`limristem_roundcube\`.* TO 'roundcube'@'localhost' IDENTIFIED BY '$db_pass'; GRANT ALL PRIVILEGES ON \`limristem_roundcube\`.* TO 'roundcube'@'127.0.0.1' IDENTIFIED BY '$db_pass'; FLUSH PRIVILEGES;" 2>/dev/null || true
  printf '%s\n' "$db_pass"
}

configure_nginx_webmail() {
  local sock_path nginx_conf
  sock_path=$(detect_php_fpm_sock)
  nginx_conf=""
  for cfg in "/etc/nginx/sites-available/limristem-mail-api.conf" "/etc/nginx/sites-available/limristem-mail.conf" "/etc/nginx/sites-available/default"; do
    if [[ -f "$cfg" ]]; then
      nginx_conf="$cfg"
      break
    fi
  done

  if [[ -n "$nginx_conf" ]]; then
    echo "[Webmail] Configuring NGINX /webmail and /mail locations pointing to /public_html with fallback to /public_html/index.php in $nginx_conf..." >&2
    python3 - "$nginx_conf" "$sock_path" <<'PY'
import sys, re

conf_file = sys.argv[1]
sock = sys.argv[2]

content = open(conf_file, "r").read()

webmail_block = f"""
    # Roundcube Webmail Locations
    location /webmail/ {{
        alias /var/www/roundcube/public_html/;
        index index.php;
        try_files $uri $uri/ /webmail/index.php?$args;

        location ~ ^/webmail/(.+\\.php)(/.*)?$ {{
            alias /var/www/roundcube/public_html/$1;
            include fastcgi_params;
            fastcgi_pass unix:{sock};
            fastcgi_param SCRIPT_FILENAME /var/www/roundcube/public_html/$1;
            fastcgi_param PATH_INFO $2;
            fastcgi_param SCRIPT_NAME /webmail/$1;
        }}
    }}

    location = /webmail {{
        return 301 /webmail/;
    }}

    location /mail {{
        return 301 /webmail/;
    }}
"""

# Strip existing webmail block if present
content = re.sub(r'# Roundcube Webmail Locations.*?(?=location / \{)', '', content, flags=re.DOTALL)

pos = content.find("location / {")
if pos != -1:
    updated = content[:pos] + webmail_block + "\n    " + content[pos:]
    open(conf_file, "w").write(updated)
PY
    nginx -t >/dev/null 2>&1 && systemctl reload nginx || true
  fi
}

install_roundcube() {
  local target_ver=${1:-}
  if [[ -z "$target_ver" ]]; then
    target_ver=$(fetch_latest_roundcube_version)
  fi
  require_root
  load_env
  install_php_stack

  local db_pass des_key
  db_pass=$(ensure_mariadb_webmail_db)
  des_key=$(openssl rand -hex 12)

  mkdir -p /var/www
  local tarball_url="https://github.com/roundcube/roundcubemail/releases/download/${target_ver}/roundcubemail-${target_ver}-complete.tar.gz"
  local tmp_tar="/tmp/roundcube-${target_ver}.tar.gz"

  echo "[Webmail] Downloading Roundcube Webmail v${target_ver}..." >&2
  curl -sSL "$tarball_url" -o "$tmp_tar" || tarball_url="https://github.com/roundcube/roundcubemail/releases/download/1.7.1/roundcubemail-1.7.1-complete.tar.gz" && curl -sSL "$tarball_url" -o "$tmp_tar"

  echo "[Webmail] Extracting to /var/www/roundcube..." >&2
  rm -rf /tmp/roundcubemail-extract
  mkdir -p /tmp/roundcubemail-extract
  tar -xzf "$tmp_tar" -C /tmp/roundcubemail-extract
  rm -rf "$WEBMAIL_DIR"
  mv /tmp/roundcubemail-extract/roundcubemail-* "$WEBMAIL_DIR"
  rm -rf /tmp/roundcubemail-extract "$tmp_tar"

  # Initial DB schema import
  if [[ -f "$WEBMAIL_DIR/SQL/mysql.initial.sql" ]]; then
    mysql -e "DROP DATABASE IF EXISTS limristem_roundcube; CREATE DATABASE limristem_roundcube CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; GRANT ALL PRIVILEGES ON \`limristem_roundcube\`.* TO 'roundcube'@'localhost' IDENTIFIED BY '$db_pass'; GRANT ALL PRIVILEGES ON \`limristem_roundcube\`.* TO 'roundcube'@'127.0.0.1' IDENTIFIED BY '$db_pass'; FLUSH PRIVILEGES;" 2>/dev/null || true
    mysql limristem_roundcube < "$WEBMAIL_DIR/SQL/mysql.initial.sql" 2>/dev/null || true
  fi

  # Auto-generate config.inc.php
  echo "[Webmail] Auto-configuring Roundcube config.inc.php..." >&2
  cat <<EOF > "$WEBMAIL_DIR/config/config.inc.php"
<?php
\$config = array();
\$config['db_dsnw'] = 'mysqli://roundcube:${db_pass}@localhost/limristem_roundcube';
\$config['imap_host'] = 'ssl://127.0.0.1:993';
\$config['smtp_host'] = 'tls://127.0.0.1:587';
\$config['smtp_user'] = '%u';
\$config['smtp_pass'] = '%p';
\$config['imap_conn_options'] = array(
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true,
    ),
);
\$config['smtp_conn_options'] = array(
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true,
    ),
);
\$config['support_url'] = '';
\$config['product_name'] = 'Limristem eMail Webmail';
\$config['des_key'] = '${des_key}';
\$config['plugins'] = array('archive', 'zipdownload', 'password', 'managesieve', 'markasjunk');
\$config['skin'] = 'elastic';
EOF

  rm -rf "$WEBMAIL_DIR/installer"
  chown -R www-data:www-data "$WEBMAIL_DIR"
  chmod -R 755 "$WEBMAIL_DIR"

  configure_nginx_webmail

  # Update state JSON
  mkdir -p "$BASE_DIR/config"
  python3 - "$target_ver" "$STATE_FILE" <<'PY'
import json
import sys

ver = sys.argv[1]
path = sys.argv[2]

data = {
    "installed": True,
    "version": ver,
    "updated_at": __import__("time").strftime("%Y-%m-%dT%H:%M:%SZ"),
}
open(path, "w").write(json.dumps(data, indent=2))
PY

  echo "[Webmail] Roundcube Webmail v${target_ver} installed successfully!" >&2
}

upgrade_roundcube() {
  require_root
  load_env
  local current_ver latest_ver
  current_ver=$(detect_installed_version)
  latest_ver=$(fetch_latest_roundcube_version)

  echo "[Webmail] Upgrading Roundcube Webmail to latest release v${latest_ver} (current: v${current_ver})..." >&2

  local tarball_url="https://github.com/roundcube/roundcubemail/releases/download/${latest_ver}/roundcubemail-${latest_ver}-complete.tar.gz"
  local tmp_tar="/tmp/roundcube-${latest_ver}-upgrade.tar.gz"

  curl -sSL "$tarball_url" -o "$tmp_tar"
  if [[ -f "$WEBMAIL_DIR/bin/installto.sh" ]]; then
    mkdir -p /tmp/rc-up-extract
    tar -xzf "$tmp_tar" -C /tmp/rc-up-extract
    local extracted_dir
    extracted_dir=$(ls -d /tmp/rc-up-extract/roundcubemail-* | head -n 1)
    if [[ -d "$extracted_dir" ]]; then
      "$extracted_dir/bin/installto.sh" -y "$WEBMAIL_DIR" || true
    fi
    rm -rf /tmp/rc-up-extract "$tmp_tar"
  else
    install_roundcube "$latest_ver"
  fi

  if [[ -f "$WEBMAIL_DIR/bin/updatedb.sh" ]]; then
    "$WEBMAIL_DIR/bin/updatedb.sh" --dir "$WEBMAIL_DIR/SQL" --package roundcube || true
  fi

  chown -R www-data:www-data "$WEBMAIL_DIR"
  systemctl reload nginx || true
  systemctl restart php*-fpm 2>/dev/null || true

  echo "[Webmail] Roundcube Webmail upgraded to v${latest_ver} successfully!" >&2
}

set_auto_update() {
  local val=${1:-no}
  require_root
  load_env
  limristem_mail_upsert_env_value "$ENV_FILE" "LIMRISTEM_MAIL_WEBMAIL_AUTO_UPDATE" "$val"
  echo "[Webmail] Webmail auto-update set to $val" >&2
}

remove_webmail() {
  require_root
  rm -rf "$WEBMAIL_DIR"
  rm -f "$STATE_FILE"
  echo "[Webmail] Roundcube Webmail files removed." >&2
}

require_root
load_env

# Allow panel escape namespace if needed
case "${1:-}" in
  install|upgrade|set-auto-update|remove)
    limristem_mail_escape_write_namespace LIMRISTEM_MAIL_WEBMAIL_WORKER limristem-mail-webmail "$@"
    ;;
esac

command=${1:-status}
case "$command" in
  status)
    get_status_json
    ;;
  install)
    shift
    ver=""
    while [[ $# -gt 0 ]]; do
      case "$1" in
        --version)
          ver="$2"
          shift 2
          ;;
        *)
          shift
          ;;
      esac
    done
    install_roundcube "${ver:-$DEFAULT_ROUNDCUBE_VERSION}"
    get_status_json
    ;;
  upgrade)
    upgrade_roundcube
    get_status_json
    ;;
  set-auto-update)
    set_auto_update "${2:-no}"
    get_status_json
    ;;
  remove)
    remove_webmail
    get_status_json
    ;;
  *)
    usage >&2
    exit 1
    ;;
esac
