//    \\ SPIKE: Secure your secrets with SPIFFE. — https://spike.ist/
//  \\\\\ Copyright 2024-present SPIKE contributors.
// \\\\\\\ SPDX-License-Identifier: Apache-2.0

package net

import (
	"github.com/spiffe/go-spiffe/v2/workloadapi"
	"github.com/spiffe/spike-sdk-go/config/env"
	sdkErrors "github.com/spiffe/spike-sdk-go/errors"
	"github.com/spiffe/spike-sdk-go/log"
	"github.com/spiffe/spike-sdk-go/net"
	"github.com/spiffe/spike-sdk-go/predicate"

	http "github.com/spiffe/spike/app/keeper/internal/route/base"
	routing "github.com/spiffe/spike/internal/net"
)

// Serve initializes and starts a TLS-secured HTTP server for the given
// application.
//
// Serve uses the provided X509Source for TLS authentication and configures the
// server with the specified HTTP routes. It will listen on the port specified
// by the TLS port environment variable. If the server fails to start, it logs a
// fatal error and terminates the application.
//
// Parameters:
//   - appName: A string identifier for the application, used in error messages
//   - source: An X509Source that provides TLS certificates for the server.
//     Must not be nil.
//
// The function does not return unless an error occurs, in which case it calls
// log.FatalLn and terminates the program.
func Serve(appName string, source *workloadapi.X509Source) {
	if source == nil {
		log.FatalErr(appName, *sdkErrors.ErrSPIFFENilX509Source)
	}

	if err := net.ServeWithPredicate(
		source,
		func() { routing.HandleRoute(http.Route) },
		// Security: Only SPIKE Nexus and SPIKE Bootstrap
		// can talk to SPIKE Keepers.
		predicate.AllowKeeperPeer,
		env.KeeperTLSPortVal(),
	); err != nil {
		log.FatalErr(appName, *err)
	}
}
