package api

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"log"
	"net"
	"os"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/reflection"

	pb "deevirt.fr/compute/pkg/api/proto"
	"deevirt.fr/compute/pkg/config"
	"deevirt.fr/compute/pkg/raft"
)

func createGRPCServer(conf *config.Config) *grpc.Server {
	if conf.Manager.TlsKey != "" {
		cert, err := tls.LoadX509KeyPair(conf.Manager.TlsCert, conf.Manager.TlsKey)
		if err != nil {
			log.Fatalf("Erreur chargement du certificat: %v", err)
		}

		// Charger la CA (facultatif, pour la vérification des clients)
		caCert, err := os.ReadFile(conf.Manager.TlsCert)
		if err != nil {
			log.Fatalf("Erreur chargement CA: %v", err)
		}
		certPool := x509.NewCertPool()
		certPool.AppendCertsFromPEM(caCert)

		// Créer les credentials TLS
		creds := credentials.NewTLS(&tls.Config{
			Certificates: []tls.Certificate{cert},
			ClientCAs:    certPool,
			ClientAuth:   tls.RequireAndVerifyClientCert, // Authentification mutuelle (mTLS),
		})

		return grpc.NewServer(grpc.Creds(creds))
	}

	return grpc.NewServer()
}

func Server() {
	//ctx := context.Background()

	// Récupération de la configuration deevirt
	conf, err := config.New()
	if err != nil {
		log.Fatalf("failed load configuration: %v", err)
	}

	sock, err := net.Listen("tcp", fmt.Sprintf(":%d", 4480))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	r := raft.New(conf, 4480)

	tm, err := r.Open()
	if err != nil {
		log.Fatalf("failed to start raft: %v", err)
	}

	s := createGRPCServer(conf)
	pb.RegisterDomainServer(s, &Domain{
		Config: conf,
		Store:  r,
	})
	tm.Register(s)
	//leaderhealth.Setup(r, s, []string{"Example"})
	raft.Register(s, r.Raft)
	reflection.Register(s)
	if err := s.Serve(sock); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}
