package server

import (
	"context"
	"epur-pay/cache"
	"epur-pay/model"
	"epur-pay/pkg/config"
	"epur-pay/pkg/limit"
	"epur-pay/pkg/logger"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"time"
)

func (p *App) WaitServerAppListen() {

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)
	sig := <-signalChan

	logger.AccessLogger.Warnln("Get Signal:", sig, " Shutdown Server ...")

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

	for _, v := range p.ServerApps {
		if err := v.Shutdown(ctx); err != nil {
			logger.AccessLogger.Errorln("Shutdown: ", err)
		}
	}
	logger.AccessLogger.Infoln("server exiting")
}

func (p *App) ListenServerApp() *App {
	for _, v := range p.ServerApps {
		go func(v *http.Server) {
			if err := v.ListenAndServe(); err != nil {
				logger.AccessLogger.Warnf("HTTP listen: %s\n", err)
			}
		}(v)
	}

	go func() {
		for !cache.Global.ProjectInitStatus {
			time.Sleep(100 * time.Millisecond)
		}
		if p.RunMode == "release" {
			cache.Global.LimitRouter.Api = limit.NewUriLimiter().
				AddBucketByConf(cache.Global.LimitRouter.Rule.Rules)
		}
	}()

	logger.AccessLogger.Infof("server listening ...")
	return p
}

func (p *App) AddServerApp(s1 model.ListenServer, r http.Handler) *App {

	endPoint := fmt.Sprintf(":%d", s1.Port)

	logger.AccessLogger.Infoln(endPoint)
	ReadTimeout := time.Second
	WriteTimeout := time.Second

	if config.Cf.Common.RunMode == "release" {
		ReadTimeout = s1.ReadTimeOut * time.Second
		WriteTimeout = s1.WriteTimeOut * time.Second
	} else {
		ReadTimeout = 60 * 60 * time.Second
		WriteTimeout = 60 * 60 * time.Second
	}

	p.ServerApps = append(p.ServerApps, &http.Server{
		Addr:           endPoint,
		Handler:        r,
		ReadTimeout:    ReadTimeout,
		WriteTimeout:   WriteTimeout,
		MaxHeaderBytes: 1 << 20,
	})
	return p
}