package main

import (
	"fmt"
	"net/http"
	"strconv"
	"time"

	"log"

	"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/common"
	"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/mocks"
	"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/models"
	"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/rootmux"
	"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/tokens"
)

var (
	httpsPort      = common.IntValueFromEnv("HTTPS_PORT", 443)         // HTTPS port to serve on
	debugMode      = common.BoolValueFromEnv("DEBUG_MODE", false)      // Debug mode, disable Secure attribute for cookies
	mockOAuth2     = common.BoolValueFromEnv("MOCK_OAUTH2", false)     // Enable mock OAuth2 login
	fetchGrdfToken = common.BoolValueFromEnv("FETCH_GRDF_TOKEN", true) // HTTPS port to serve on
)

func main() {

	log.Printf("--- Server is starting on port %v ---", httpsPort)

	// Initializations
	tokens.Init("./mnt/configs/tokenskey.json", debugMode)

	// Create the server
	rootMux := rootmux.CreateRootMux()

	// Init the hostname
	mocks.Init(httpsPort)

	// Start a mock oauth2 server if debug mode is on
	if mockOAuth2 {
		mockOAuth2Port := ":8090"
		go http.ListenAndServe(mockOAuth2Port, mocks.CreateMockOAuth2())
		fmt.Println("Mock OAuth2 server Listening on: http://localhost" + mockOAuth2Port)
	}

	quit := make(chan struct{})

	// If needed, we shall request a new GRDF token every 2-hours
	if fetchGrdfToken {
		// Call the function immediately when the server starts
		models.FetchGRDFAuthAPI()

		// then call GRDF auth api every two hours
		ticker := time.NewTicker(time.Hour * 2)
		go func() {
			for {
				select {
				case <-ticker.C:
					models.FetchGRDFAuthAPI()
				case <-quit:
					ticker.Stop()
					return
				}
			}
		}()
	}

	// Deletes outdated consents every 24h
	dh := models.NewDataHandler()
	dailyTicker := time.NewTicker(time.Hour * 24)
	go func() {
		for {
			select {
			case <-dailyTicker.C:
				models.DeleteOutdatedConsents(dh)
			case <-quit:
				dailyTicker.Stop()
				return
			}
		}
	}()

	// Serve locally with https
	log.Fatal(http.ListenAndServeTLS(":"+strconv.Itoa(httpsPort), "./dev_certificates/localhost.crt", "./dev_certificates/localhost.key", rootMux.Router))
	// log.Fatal(http.ListenAndServe(":"+strconv.Itoa(httpsPort), rootMux.Router))
}