package main

import (
  "log"
  "net/http"
  "time"

  "github.com/gorilla/mux"
  httpSwagger "github.com/swaggo/http-swagger"
  _ "github.com/your-org/03.wireguard-policy/app/docs"
  "gorm.io/driver/sqlite"
  "gorm.io/gorm"
)

// @title WGRplane API
// @version 1.0
// @description WireGuard Control Plane with Dynamic Policy Firewall. REST API for managing WireGuard servers, peers, webhooks, SMTP settings, and real-time stats.
// @contact.name API Support
// @host localhost:10087
// @BasePath /
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name wg-rplane-datadunia
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization

// Global plugin manager (optional for runtime notifications)
var pluginManager *PluginManager

func initApp() *gorm.DB {
  // Initialize the database. We use a local SQLite database in the app folder.
  dbConn, err := gorm.Open(sqlite.Open("wgrplane.db"), &gorm.Config{})
  if err != nil {
    log.Fatalf("failed to connect to database: %v", err)
  }
  // Auto-migrate all relevant models
  if err := dbConn.AutoMigrate(&Server{}, &Peer{}, &Webhook{}, &SMTPSettings{}); err != nil {
    log.Fatalf("failed to migrate database: %v", err)
  }
  // Expose the global db for handlers.go
  db = dbConn
  return dbConn
}

// Entry point to bootstrapped server
func main() {
  // Initialize DB and migrations
  db := initApp()
  _ = db // keep reference for linter

  // Initialize plugin manager and load sample plugins
  pluginManager = NewPluginManager()
  pluginManager.LoadPlugins()

  // Initialize background components
  initWebhookEngine()
  initScheduler()

  // Initialize HTTP routes
  r := mux.NewRouter()
  // Servers
  r.HandleFunc("/api/servers", getServers).Methods("GET")
  r.HandleFunc("/api/servers", createServer).Methods("POST")
  r.HandleFunc("/api/servers/{id}", getServer).Methods("GET")
  r.HandleFunc("/api/servers/{id}", updateServer).Methods("PUT")
  r.HandleFunc("/api/servers/{id}", deleteServer).Methods("DELETE")
  // Peers
  r.HandleFunc("/api/servers/{id}/peers", getServerPeers).Methods("GET")
  r.HandleFunc("/api/servers/{id}/peers", createServerPeer).Methods("POST")
  r.HandleFunc("/api/peers/{id}", updatePeer).Methods("PUT")
  r.HandleFunc("/api/peers/{id}", deletePeer).Methods("DELETE")
  // SMTP settings
  r.HandleFunc("/api/settings/smtp", getSMTPSettings).Methods("GET")
  r.HandleFunc("/api/settings/smtp", setSMTPSettings).Methods("POST")
  // Webhooks
  r.HandleFunc("/api/servers/{id}/webhooks", getServerWebhooks).Methods("GET")
  r.HandleFunc("/api/servers/{id}/webhooks", createServerWebhook).Methods("POST")
  r.HandleFunc("/api/webhooks/{id}", deleteWebhook).Methods("DELETE")
  // Peer config / QR
  r.HandleFunc("/api/peers/{id}/config", getPeerConfig).Methods("GET")
  r.HandleFunc("/api/peers/{id}/qrcode", getPeerQRCode).Methods("GET")
  // Stats
  r.HandleFunc("/api/stats", getStats).Methods("GET")
  r.HandleFunc("/api/servers/{id}/stats", getServerStats).Methods("GET")

  // Swagger documentation
  r.PathPrefix("/swagger/").Handler(httpSwagger.WrapHandler)

  // Start HTTP server
  srv := &http.Server{Addr: ":10087", Handler: r, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second}
  log.Println("server: listening on :10087")
  if err := srv.ListenAndServe(); err != nil {
    log.Fatalf("server: failed to start: %v", err)
  }
}
