package httpserver

import (
	"net/http"
)

// Server exposes the REST control plane for the service.
type Server struct {
	serviceName string
	ready       func() bool
	mux         *http.ServeMux
}

// New creates a REST server with standard health endpoints.
// When sync is non-nil, admin ingestion routes are registered.
// When forceSync is non-nil, POST /admin/repos/{repo_id}/force-sync is registered.
// When importAcceptor is non-nil, POST /repos/import is registered.
// When metadata is non-nil, repository/snapshot GET routes are registered.
// When indexedRepos is non-nil, GET /indexed-repos is registered.
// When webhook is non-nil, POST /webhooks/bitbucket is registered.
func New(serviceName string, ready func() bool, sync SyncTrigger, forceSync ForceSyncTrigger, importAcceptor ImportAcceptor, metadata MetadataReader, indexedRepos IndexedRepoLister, webhook http.Handler, gatewayInternalSecret string) *Server {
	s := &Server{
		serviceName: serviceName,
		ready:       ready,
		mux:         http.NewServeMux(),
	}

	s.mux.HandleFunc("GET /{$}", handleRoot(serviceName))
	s.mux.HandleFunc("GET /healthz", handleHealthz(serviceName))
	s.mux.HandleFunc("GET /readyz", handleReadyz(serviceName, ready))
	s.mux.HandleFunc("GET /version", handleVersion(serviceName))

	if sync != nil {
		s.mux.HandleFunc("POST /admin/repos/{repo_id}/sync", handleAdminRepoSync(sync))
	}
	if forceSync != nil {
		s.mux.HandleFunc("POST /admin/repos/{repo_id}/force-sync", handleAdminRepoForceSync(forceSync))
	}
	if importAcceptor != nil {
		s.mux.HandleFunc("POST /repos/import", handleRepoImport(importAcceptor))
	}
	if metadata != nil {
		s.mux.HandleFunc("GET /repos/{repo_id}", handleGetRepository(metadata))
		s.mux.HandleFunc("GET /repos/{repo_id}/status", handleGetRepoStatus(metadata))
		s.mux.HandleFunc("GET /repos/{repo_id}/snapshots/{snapshot_id}", handleGetSnapshot(metadata))
		s.mux.HandleFunc("GET /repos/{repo_id}/indexing-runs/latest", handleGetLatestIndexingRun(metadata))
		s.mux.HandleFunc("GET /repos/{repo_id}/snapshots/{snapshot_id}/indexing-run", handleGetIndexingRunBySnapshot(metadata))
		s.mux.HandleFunc("GET /repos/{repo_id}/snapshots/{snapshot_id}/indexing-run/diagnostics", handleGetIndexingDiagnostics(metadata))
	}
	if indexedRepos != nil {
		s.mux.HandleFunc("GET /indexed-repos", handleListIndexedRepos(indexedRepos, gatewayInternalSecret))
	}
	if webhook != nil {
		s.mux.Handle("POST /webhooks/bitbucket", webhook)
	}

	return s
}

// Handler returns the underlying HTTP handler.
func (s *Server) Handler() http.Handler {
	return s.mux
}
