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

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

edition="${1:-}"
if [[ -z "$edition" ]]; then
  echo "Usage: $0 <mail-only|mail-google|mail-native-zimbra|mailmali-google-connect>"
  exit 1
fi

case "$edition" in
  mail-only|mail-google|mail-native-zimbra|mailmali-google-connect) ;;
  *)
    echo "Unknown edition: $edition"
    exit 1
    ;;
esac

case "$edition" in
  mail-only)
    product_edition="mail_only"
    ;;
  mail-google)
    product_edition="mail_google"
    ;;
  mailmali-google-connect)
    product_edition="mail_google"
    ;;
  mail-native-zimbra)
    product_edition="mail_native_zimbra"
    ;;
esac

bundle_dir="$ROOT_DIR/$edition"
if [[ ! -d "$bundle_dir" ]]; then
  echo "Missing bundle directory: $bundle_dir"
  exit 1
fi
package_tier_lock=""
package_edition_lock=""
package_source_sku_lock=""
package_demo_login_lock=""
if [[ -f "$bundle_dir/package.env" ]]; then
  # shellcheck source=/dev/null
  source "$bundle_dir/package.env"
  package_tier_lock="${ZIMPHONY_PACKAGE_TIER_LOCK:-}"
  package_edition_lock="${ZIMPHONY_PACKAGE_EDITION_LOCK:-}"
  package_source_sku_lock="${ZIMPHONY_PACKAGE_SOURCE_SKU_LOCK:-}"
  package_demo_login_lock="${ZIMPHONY_PACKAGE_DEMO_LOGIN_LOCK:-}"
fi
if [[ -n "$package_edition_lock" ]]; then
  product_edition="$package_edition_lock"
fi

prompt() {
  local label="$1"
  local default_value="${2:-}"
  local value=""
  if [[ -n "$default_value" ]]; then
    read -r -p "$label [$default_value]: " value
    printf '%s\n' "${value:-$default_value}"
  else
    read -r -p "$label: " value
    printf '%s\n' "$value"
  fi
}

prompt_env() {
  local env_name="$1"
  local label="$2"
  local default_value="${3:-}"
  local value="${!env_name:-}"
  if [[ -n "$value" ]]; then
    printf '%s\n' "$value"
    return
  fi
  if [[ "${NONINTERACTIVE:-0}" == "1" ]]; then
    if [[ -n "$default_value" ]]; then
      printf '%s\n' "$default_value"
      return
    fi
    echo "Missing required env var: $env_name" >&2
    exit 1
  fi
  prompt "$label" "$default_value"
}

optional_env() {
  local env_name="$1"
  local label="$2"
  local value="${!env_name:-}"
  if [[ -n "$value" ]]; then
    printf '%s\n' "$value"
    return
  fi
  if [[ "${NONINTERACTIVE:-0}" == "1" ]]; then
    printf '\n'
    return
  fi
  prompt "$label" ""
}

write_env() {
  local file="$1"
  shift
  local old_umask
  old_umask="$(umask)"
  umask 077
  {
    printf '%s\n' "$@"
  } > "$file"
  umask "$old_umask"
  chmod 600 "$file"
}

derive_admin_soap_url() {
  local public_url="$1"
  local base="${public_url%%/service/*}"
  if [[ -z "$base" || "$base" == "$public_url" ]]; then
    base="$public_url"
  fi
  if [[ "$base" =~ ^https://([^/:]+)(:[0-9]+)?$ ]]; then
    printf 'https://%s:7071/service/admin/soap\n' "${BASH_REMATCH[1]}"
    return
  fi
  if [[ "$base" =~ ^http://([^/:]+)(:[0-9]+)?$ ]]; then
    printf 'https://%s:7071/service/admin/soap\n' "${BASH_REMATCH[1]}"
    return
  fi
  printf '%s\n' 'https://zimbra.example.com:7071/service/admin/soap'
}

echo "Zimphony webmail Docker install wizard"
echo "Selected edition: $edition"
if [[ "${NONINTERACTIVE:-0}" == "1" ]]; then
  echo "Mode: non-interactive (env preseed)"
else
  echo "Mode: interactive"
fi
echo

webmail_host="$(prompt_env WEBMAIL_HOST 'Webmail host (for example mail.example.com)' 'mail.example.com')"
zimbra_soap_url="$(prompt_env ZIMBRA_SOAP_URL 'Mail server user SOAP URL' "https://${webmail_host}/service/soap")"
zimbra_admin_soap_url="${ZIMBRA_PROVISIONING_URL:-${ZIMBRA_ADMIN_SOAP_URL:-}}"
if [[ -z "$zimbra_admin_soap_url" ]]; then
  zimbra_admin_soap_url="$(prompt_env ZIMBRA_ADMIN_SOAP_URL 'Mail server admin SOAP URL' "$(derive_admin_soap_url "$zimbra_soap_url")")"
fi
zimbra_admin_email="$(prompt_env ZIMBRA_ADMIN_EMAIL 'Mail server admin email' 'admin@example.com')"
zimbra_admin_password="$(prompt_env ZIMBRA_ADMIN_PASSWORD 'Mail server admin password')"
zimbra_os_version="${ZIMBRA_OS_VERSION:-}"
product_tier="${PRODUCT_TIER:-}"
if [[ -n "$package_tier_lock" ]]; then
  product_tier="$package_tier_lock"
elif [[ -z "$product_tier" ]]; then
  case "$product_edition" in
    mail_google) product_tier="google_connect" ;;
    mail_native_zimbra) product_tier="zimbra_native" ;;
    *) product_tier="shared_webmail" ;;
  esac
fi
case "$product_tier" in
  free|shared_webmail)
    default_source_sku="encoded_unlimited"
    ;;
  zimbra_native|google_connect)
    default_source_sku="encoded_per_mailbox"
    ;;
  mailmali_google_connect|mailmali-google-connect)
    product_tier="mailmali_google_connect"
    default_source_sku="encoded_per_mailbox"
    ;;
  *)
    default_source_sku="encoded_per_mailbox"
    ;;
esac
source_sku="${SOURCE_SKU:-$default_source_sku}"
if [[ -n "$package_source_sku_lock" ]]; then
  source_sku="$package_source_sku_lock"
fi
license_server_url="${LICENSE_SERVER_URL:-https://license.zimphony.com}"
license_key="${ZIMPHONY_LICENSE_KEY:-}"
license_installation_id="${ZIMPHONY_INSTALLATION_ID:-}"
license_check_signing_secret="${LICENSE_CHECK_SIGNING_SECRET:-}"
license_required=1
if [[ "$product_tier" == "free" || "$product_tier" == "mailmali_google_connect" ]]; then
  license_required=0
fi
if [[ "$license_required" == "1" ]]; then
  license_server_url="$(prompt_env LICENSE_SERVER_URL 'License server URL' "$license_server_url")"
  license_key="$(prompt_env ZIMPHONY_LICENSE_KEY 'Zimphony license key')"
  license_check_signing_secret="$(prompt_env LICENSE_CHECK_SIGNING_SECRET 'License check signing secret')"
  license_installation_id="${license_installation_id:-${webmail_host}}"
else
  license_server_url=""
  license_key=""
  license_installation_id=""
  license_check_signing_secret=""
fi
brand_name="${BRAND_NAME:-${ZIMPHONY_BRAND_NAME:-}}"
while [[ -z "$brand_name" ]]; do
  brand_name="$(prompt_env BRAND_NAME 'Brand name' 'Zimphony Webmail')"
  if [[ -z "$brand_name" ]]; then
    echo "Brand name is required."
  fi
done
brand_tagline="${BRAND_TAGLINE:-${ZIMPHONY_BRAND_TAGLINE:-}}"
if [[ -z "$brand_tagline" ]]; then
  brand_tagline="$(prompt_env BRAND_TAGLINE 'Brand tagline' 'Business email that grows with you')"
fi
brand_logo_url="${BRAND_LOGO_URL:-${ZIMPHONY_BRAND_LOGO_URL:-}}"
if [[ -z "$brand_logo_url" ]]; then
  brand_logo_url="$(optional_env BRAND_LOGO_URL 'Brand logo URL')"
fi
brand_favicon_url="${BRAND_FAVICON_URL:-${ZIMPHONY_BRAND_FAVICON_URL:-}}"
if [[ -z "$brand_favicon_url" ]]; then
  brand_favicon_url="$(optional_env BRAND_FAVICON_URL 'Brand favicon URL')"
fi
admin_help_text="$(prompt_env ADMIN_HELP_TEXT 'Customer admin help text' 'Help : support@example.com')"
brand_logo_alt="${brand_name} logo"
frontend_origin="https://${webmail_host}"
frontend_origins="${frontend_origin}"
demo_login_enabled="${DEMO_LOGIN_ENABLED:-false}"
if [[ "$package_demo_login_lock" == "true" ]]; then
  demo_login_enabled="true"
fi
demo_login_email="${DEMO_LOGIN_EMAIL:-}"
demo_login_password="${DEMO_LOGIN_PASSWORD:-}"

backend_env=(
  "FRONTEND_ORIGIN=${frontend_origin}"
  "FRONTEND_ORIGINS=${frontend_origins}"
  "SESSION_SECURE=true"
  "DATABASE_URL=sqlite:////app/data/platform.db"
  "PRODUCT_EDITION=${product_edition}"
  "ZIMPHONY_PACKAGE_EDITION_LOCK=${package_edition_lock}"
  "PRODUCT_TIER=${product_tier}"
  "ZIMPHONY_PACKAGE_TIER_LOCK=${package_tier_lock}"
  "SOURCE_SKU=${source_sku}"
  "ZIMPHONY_PACKAGE_SOURCE_SKU_LOCK=${package_source_sku_lock}"
  "LICENSE_SERVER_URL=${license_server_url}"
  "ZIMPHONY_LICENSE_KEY=${license_key}"
  "ZIMPHONY_INSTALLATION_ID=${license_installation_id}"
  "LICENSE_CHECK_SIGNING_SECRET=${license_check_signing_secret}"
  "LICENSE_CACHE_PATH=/app/data/license-status-cache.json"
  "LICENSE_ACTIVATION_STATE_PATH=/app/data/license-activation-state.json"
  "LICENSE_ACTIVATION_GRACE_DAYS=${LICENSE_ACTIVATION_GRACE_DAYS:-15}"
  "LICENSE_CHECK_INTERVAL_SECONDS=${LICENSE_CHECK_INTERVAL_SECONDS:-21600}"
  "LICENSE_CHECK_TIMEOUT_SECONDS=${LICENSE_CHECK_TIMEOUT_SECONDS:-8}"
  "BRAND_NAME=${brand_name}"
  "BRAND_TAGLINE=${brand_tagline}"
  "BRAND_LOGO_URL=${brand_logo_url}"
  "BRAND_LOGO_ALT=${brand_logo_alt}"
  "BRAND_FAVICON_URL=${brand_favicon_url}"
  "ADMIN_HELP_TEXT=${admin_help_text}"
  "CANONICAL_MAIL_HOST=${webmail_host}"
  "CUSTOMER_REDIRECT_PREFIX=mail"
  "ZIMBRA_PROVISIONING_URL=${zimbra_admin_soap_url}"
  "ZIMBRA_ADMIN_EMAIL=${zimbra_admin_email}"
  "ZIMBRA_ADMIN_PASSWORD=${zimbra_admin_password}"
  "ZIMBRA_OS_VERSION=${zimbra_os_version}"
  "DEFAULT_ZIMBRA_SOAP_URL=${zimbra_soap_url}"
  "DEFAULT_ZIMBRA_VERIFY_SSL=false"
  "IMAPSYNC_BINARY=imapsync"
)

if [[ "$demo_login_enabled" == "true" ]]; then
  if [[ -z "$demo_login_email" || -z "$demo_login_password" ]]; then
    if [[ "${NONINTERACTIVE:-0}" == "1" ]]; then
      echo "DEMO_LOGIN_EMAIL and DEMO_LOGIN_PASSWORD are required when DEMO_LOGIN_ENABLED=true" >&2
      exit 1
    fi
    demo_login_email="$(prompt_env DEMO_LOGIN_EMAIL 'Demo mailbox email')"
    demo_login_password="$(prompt_env DEMO_LOGIN_PASSWORD 'Demo mailbox password')"
  fi
  backend_env+=(
    "DEMO_LOGIN_ENABLED=true"
    "DEMO_LOGIN_EMAIL=${demo_login_email}"
    "DEMO_LOGIN_PASSWORD=${demo_login_password}"
  )
fi

case "$edition" in
  mail-google|mailmali-google-connect)
    google_client_id="$(prompt_env GOOGLE_CLIENT_ID 'Google client ID')"
    google_client_secret="$(prompt_env GOOGLE_CLIENT_SECRET 'Google client secret')"
    google_redirect_uri="https://${webmail_host}/calendar/oauth/callback"
    google_webhook_uri="https://${webmail_host}/calendar/webhook"
    backend_env+=(
      "GOOGLE_CLIENT_ID=${google_client_id}"
      "GOOGLE_CLIENT_SECRET=${google_client_secret}"
      "GOOGLE_REDIRECT_URI=${google_redirect_uri}"
      "GOOGLE_CALENDAR_WEBHOOK_URL=${google_webhook_uri}"
    )
    ;;
  mail-native-zimbra)
    if [[ "$package_demo_login_lock" == "true" ]]; then
      google_client_id="$(prompt_env GOOGLE_CLIENT_ID 'Google client ID for Google demo access')"
      google_client_secret="$(prompt_env GOOGLE_CLIENT_SECRET 'Google client secret for Google demo access')"
      google_redirect_uri="https://${webmail_host}/calendar/oauth/callback"
      google_webhook_uri="https://${webmail_host}/calendar/webhook"
      backend_env+=(
        "GOOGLE_CLIENT_ID=${google_client_id}"
        "GOOGLE_CLIENT_SECRET=${google_client_secret}"
        "GOOGLE_REDIRECT_URI=${google_redirect_uri}"
        "GOOGLE_CALENDAR_WEBHOOK_URL=${google_webhook_uri}"
      )
    fi
    ;;
esac

frontend_env=(
  "NEXT_PUBLIC_API_URL=http://backend:8000"
  "INTERNAL_API_UPSTREAM=http://backend:8000"
  "INTERNAL_ADMIN_API_UPSTREAM=http://backend:8000"
  "NEXT_PUBLIC_ROOT_DOMAIN=${webmail_host#*.}"
  "NEXT_PUBLIC_WEBMAIL_HOST=${webmail_host}"
  "NEXT_PUBLIC_WEBMAIL_URL=https://${webmail_host}"
  "NEXT_PUBLIC_BRAND_NAME=${brand_name}"
  "NEXT_PUBLIC_BRAND_TAGLINE=${brand_tagline}"
  "NEXT_PUBLIC_BRAND_LOGO_URL=${brand_logo_url}"
  "NEXT_PUBLIC_BRAND_LOGO_ALT=${brand_logo_alt}"
  "NEXT_PUBLIC_BRAND_FAVICON_URL=${brand_favicon_url}"
  "NEXT_PUBLIC_ADMIN_HELP_TEXT=${admin_help_text}"
)

if [[ "$edition" == "mailmali-google-connect" ]]; then
  frontend_env+=(
    "NEXT_PUBLIC_PRODUCT_FLAVOR=mailmali-google-connect"
    "NEXT_PUBLIC_MAILMALI_BAP_READONLY_API_ENABLED=false"
    "NEXT_PUBLIC_MAILMALI_BAP_API_BASE_URL="
  )
fi

write_env "$bundle_dir/backend.env" "${backend_env[@]}"
write_env "$bundle_dir/frontend.env" "${frontend_env[@]}"

echo
echo "Wrote:"
echo "  $bundle_dir/backend.env"
echo "  $bundle_dir/frontend.env"
echo
if [[ "${SKIP_START:-0}" == "1" ]]; then
  echo "SKIP_START=1, Docker stack was not started."
  exit 0
fi

echo "Starting Docker stack..."
docker compose -f "$bundle_dir/docker-compose.yml" up -d --build
echo
echo "Done."
echo "Open:"
echo "  https://${webmail_host}"
