package rest

import (
	"context"
	"net/http"
	"os"
	"os/signal"
	"time"

	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	v1 "gitlab.com/gitlab-org/spamcheck/api/v1"
	"google.golang.org/grpc"
	"gitlab.com/gitlab-org/labkit/log"
	"gitlab.com/gitlab-org/labkit/tracing"
	"gitlab.com/gitlab-org/labkit/metrics"
)

// RunServer runs HTTP/REST gateway
func RunServer(ctx context.Context, grpcPort, httpPort string) error {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	mux := runtime.NewServeMux()
	opts := []grpc.DialOption{grpc.WithInsecure()}

	if err := v1.RegisterSpamcheckServiceHandlerFromEndpoint(ctx, mux, "localhost:"+grpcPort, opts); err != nil {
		log.WithError(err).Error("failed to start HTTP gateway")
	}

	newMetricHandlerFunc := metrics.NewHandlerFactory(metrics.WithNamespace("spamcheck"))
	
	srv := &http.Server{
		Addr:    ":" + httpPort,
		Handler: newMetricHandlerFunc(tracing.Handler(mux)),
	}
	log.Info("Metrics listeners started")

	// graceful shutdown
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for range c {
			// sig is a ^C, handle it
		}

		_, cancel := context.WithTimeout(ctx, 5*time.Second)
		defer cancel()

		_ = srv.Shutdown(ctx)
	}()

	log.Info("Starting HTTP/REST gateway...")
	return srv.ListenAndServe()
}
