//
// Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
// Ministerpräsidenten des Landes Schleswig-Holstein
// Staatskanzlei
// Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
//
// Lizenziert unter der EUPL, Version 1.2 oder - sobald
// diese von der Europäischen Kommission genehmigt wurden -
// Folgeversionen der EUPL ("Lizenz");
// Sie dürfen dieses Werk ausschließlich gemäß
// dieser Lizenz nutzen.
// Eine Kopie der Lizenz finden Sie hier:
//
// https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
//
// Sofern nicht durch anwendbare Rechtsvorschriften
// gefordert oder in schriftlicher Form vereinbart, wird
// die unter der Lizenz verbreitete Software "so wie sie
// ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
// ausdrücklich oder stillschweigend - verbreitet.
// Die sprachspezifischen Genehmigungen und Beschränkungen
// unter der Lizenz sind dem Lizenztext zu entnehmen.
//

package server

import (
	"context"
	"fmt"
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/status"
	pb "info-manager-proxy/gen/go"
	log "github.com/sirupsen/logrus"
	"net/http"
)

func RegisterHomeEndpoint(mux *runtime.ServeMux) {
	err := mux.HandlePath("GET", "/", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
		defer func() {
			if err := recover(); err != nil {
				log.Error(fmt.Sprintf("failed to recover: %v", err))
				http.Error(w, fmt.Sprintf("failed to recover: %v", err), http.StatusInternalServerError)
			}
		}()
	})

	if err != nil {
		log.Fatal(fmt.Sprintf("failed to register home endpoint: %v", err))
	}
}

func RegisterInformationEndpoints(ctx context.Context, mux *runtime.ServeMux, grpcUrl string) {
	opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
	err := pb.RegisterInformationServiceHandlerFromEndpoint(ctx, mux, grpcUrl, opts)
	if err != nil {
		log.Fatal(fmt.Sprintf("failed to register information endpoints: %v", err))
	}
}

func ErrorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) {
	st, ok := status.FromError(err)
	if !ok {
		runtime.DefaultHTTPErrorHandler(ctx, mux, marshaler, w, r, err)
		return
	}

	statusCodeMap := map[codes.Code]int{
		codes.InvalidArgument: http.StatusBadRequest,
		codes.AlreadyExists:   http.StatusConflict,
		codes.Unavailable:     http.StatusServiceUnavailable,
	}

	httpStatusCode := http.StatusInternalServerError

	if code, exists := statusCodeMap[st.Code()]; exists {
		httpStatusCode = code
	}

	w.Header().Set("Content-Type", marshaler.ContentType(r))
	w.WriteHeader(httpStatusCode)

	_, writeErr := w.Write([]byte(st.Message()))
	if writeErr != nil {
		log.Fatal(fmt.Sprintf("failed to handle grpc error: %v", writeErr))
	}
}