package main

import (
	"fmt"
	"git.sch9.ru/new_gate/ms-tester/config"
	testerv1 "git.sch9.ru/new_gate/ms-tester/contracts/tester/v1"
	"git.sch9.ru/new_gate/ms-tester/internal/tester/delivery/rest"
	problemsRepository "git.sch9.ru/new_gate/ms-tester/internal/tester/repository"
	testerUseCase "git.sch9.ru/new_gate/ms-tester/internal/tester/usecase"
	"git.sch9.ru/new_gate/ms-tester/pkg"
	"github.com/gofiber/fiber/v2"
	fiberlogger "github.com/gofiber/fiber/v2/middleware/logger"
	"github.com/ilyakaznacheev/cleanenv"
	"go.uber.org/zap"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	var cfg config.Config
	err := cleanenv.ReadConfig(".env", &cfg)
	if err != nil {
		panic(fmt.Sprintf("error reading config: %s", err.Error()))
	}

	var logger *zap.Logger
	if cfg.Env == "prod" {
		logger = zap.Must(zap.NewProduction())
	} else if cfg.Env == "dev" {
		logger = zap.Must(zap.NewDevelopment())
	} else {
		panic(fmt.Sprintf(`error reading config: env expected "prod" or "dev", got "%s"`, cfg.Env))
	}

	logger.Info("connecting to postgres")
	db, err := pkg.NewPostgresDB(cfg.PostgresDSN)
	if err != nil {
		panic(err)
	}
	defer db.Close()
	logger.Info("successfully connected to postgres")

	pandocClient := pkg.NewPandocClient(&http.Client{}, cfg.Pandoc)

	problemRepo := problemsRepository.NewProblemRepository(db)
	problemUC := testerUseCase.NewProblemUseCase(problemRepo, pandocClient)

	contestRepo := problemsRepository.NewContestRepository(db)
	contestUC := testerUseCase.NewContestUseCase(contestRepo)

	server := fiber.New()

	testerv1.RegisterHandlersWithOptions(server, rest.NewTesterHandlers(problemUC, contestUC), testerv1.FiberServerOptions{
		Middlewares: []testerv1.MiddlewareFunc{
			fiberlogger.New(),
			rest.AuthMiddleware(cfg.JWTSecret),
			//rest.AuthMiddleware(cfg.JWTSecret, userUC),
			//cors.New(cors.Config{
			//	AllowOrigins:     "http://localhost:3000",
			//	AllowMethods:     "GET,POST,PUT,DELETE,OPTIONS",
			//	AllowHeaders:     "Content-Type,Set-Cookie,Credentials",
			//	AllowCredentials: true,
			//}),
		},
	})

	go func() {
		err := server.Listen(cfg.Address)
		if err != nil {
			logger.Fatal(fmt.Sprintf("error starting server: %s", err.Error()))
		}
	}()

	logger.Info(fmt.Sprintf("server started on %s", cfg.Address))

	stop := make(chan os.Signal, 1)
	signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT)

	<-stop
}