package web

import (
	"fmt"
	"strings"
	"time"

	"github.com/valyala/fasthttp"
	"go.uber.org/zap"

	"tiup-log-collector/log"
)

var (
	server *fasthttp.Server
)

type Config struct {
	Host string `json:"host"`
	Port string `json:"port"`
}

func init() {
	server = &fasthttp.Server{
		NoDefaultServerHeader: true,
		Handler:               requestHandler,
		ErrorHandler:          errorHandler,
		DisableKeepalive:      false,
		TCPKeepalive:          true,
		//TCPKeepalivePeriod: time.Second * time.Duration(65),
		IdleTimeout: time.Second * time.Duration(300),
		ReadTimeout: time.Second * time.Duration(80),
	}
}

// StartWebServer starts a blocking http server
func StartWebServer(cfg *Config) (err error) {
	fmt.Printf("Service starts running in %s:%s\n", cfg.Host, cfg.Port)
	err = server.ListenAndServe(cfg.Host + ":" + cfg.Port)

	if err != nil {
		log.L().Error("Failed to start web server", zap.String("reason", err.Error()))
	}
	return
}

// ShutdownWebServer shuts down the server
func ShutdownWebServer() {
	if server != nil {
		if err := server.Shutdown(); err != nil {
			log.L().Error("Error when shutdown", zap.Error(err))
		}
	}
}

func errorHandler(ctx *fasthttp.RequestCtx, err error) {
	log.L().Error("errorHandler", zap.Any("raw", err))
	renderMsg(ctx, fasthttp.StatusInternalServerError, err.Error())
}

func requestHandler(ctx *fasthttp.RequestCtx) {
	path := string(ctx.Path())

	if strings.HasPrefix(path, dashboardAPIPrefix) {
		dashboardHandler(ctx)
		return
	}

	switch path {
	case "/api/v1/clusters/report":
		fallthrough
	case "/api/v1/clusters/report/":
		eventHandler(ctx, "tiup-cluster")
	case "/api/v1/tidb/report":
		fallthrough
	case "/api/v1/tidb/report/":
		eventHandler(ctx, "tidb")
	case "/health_check":
		pingHandler(ctx)
	default:
		otherHandler(ctx)
	}
}
