package server

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"rpirelay/config"
	"time"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

type Server struct {
	*gin.Engine
	cfg *config.Config
}

func New(cfg *config.Config) *Server {
	e := gin.New()

	e.Use(gin.Logger())
	e.Use(gin.Recovery())

	corsCfg := cors.DefaultConfig()
	corsCfg.AllowOriginFunc = func(origin string) bool { return origin != "" }
	corsCfg.AllowCredentials = true
	corsCfg.AddAllowHeaders("Authorization")

	e.Use(cors.New(corsCfg))

	if os.Getenv("RELEASE") != "1" {
		e.Use(SwaggerServe("/api-docs", nil))
		e.GET("/api-docs.json", SwaggerSpecServe())
	}

	// set healthcheck path
	e.GET("/", func(c *gin.Context) {
		c.String(http.StatusOK, "ok")
	})

	return &Server{
		Engine: e,
		cfg:    cfg,
	}
}

func (w *Server) Start(ctx context.Context) {
	s := &http.Server{
		Handler: w,
		Addr:    fmt.Sprintf(":%d", w.cfg.Server.Port),
	}

	go func() {
		if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			s.ErrorLog.Fatal(err)
		}
	}()

	<-ctx.Done()

	c, cancel := context.WithTimeout(context.Background(), time.Second*5)
	defer cancel()

	if err := s.Shutdown(c); err != nil {
		s.ErrorLog.Fatal(err)
	}
}
