package tepapis

import (
	"fmt"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/log"
	"github.com/pingcap/tep/pkg/tepserver"
	"github.com/pingcap/tep/pkg/tepserver/filters"
	"github.com/pingcap/tep/pkg/tepserver/session"
	"go.uber.org/zap"
)

const (
	LoginPath = "/login"
)

type API struct {
	Server tepserver.Server
}

// 3 hours session timeout
const SessionMaxInactiveInterval = 3 * 60 * 60

func NewService(server *tepserver.Server) *gin.Engine {
	s := &API{Server: *server}
	r := gin.Default()
	server.SessionManager = session.NewManager(
		session.Options{
			MaxInactiveInterval: SessionMaxInactiveInterval,
			MaxAge:              0,
			HTTPOnly:            true,
			Path:                server.APIPrefix,
		},
		func(s *session.Session, event int) {
			if event == session.Created {
				log.Info("new session is created", zap.String("sessionID", s.GetMaskedSessionID()))
			} else if event == session.Destroyed {
				log.Info("session is destroyed", zap.String("sessionID", s.GetMaskedSessionID()))
			}
		},
	)

	ws := r.Group(server.APIPrefix)
	ws.Use(filters.NoCache)
	ws.Use(filters.BasicAuthenticate(server.SessionManager, server.DB, fmt.Sprintf("%s%s", server.APIPrefix, LoginPath)))

	ws.POST("/machines", s.UploadMachineFile)
	ws.GET("/machines-template", s.GetMachineTemplate)
	ws.GET("/machines/nodelabel-distribution", s.GetLabelMachines)

	ws.POST("/namespaces/:namespace/tidbcluster-schedule-backup", s.CreateScheduledBackup)
	ws.POST("/namespaces/:namespace/tidbcluster-backup", s.CreateBackup)
	ws.POST("/namespaces/:namespace/tidbcluster-restore", s.CreateRestore)
	ws.GET("/namespaces/:namespace/tidbcluster-schedule-backup/tidb-scheduled-backup-manager", s.GetScheduledBackup)
	ws.PUT("/namespaces/:namespace/tidbcluster-schedule-backup/tidb-scheduled-backup-manager", s.UpdateScheduledBackup)

	ws.POST("/metadata-schedule-backup", s.CreateMetadataScheduledBackup)
	ws.POST("/metadata-backup", s.CreateMetadataBackup)
	ws.GET("/metadata-schedule-backup/metadata-scheduled-backup-manager", s.GetMetadataScheduledBackup)
	ws.PUT("/metadata-schedule-backup/metadata-scheduled-backup-manager", s.UpdateMetadataScheduledBackup)

	ws.POST("/tidbclusters", s.CreateInstance)

	ws.POST("/logoff", s.Logout)
	ws.POST(LoginPath, s.Login)

	ws.GET("/version", s.GetVersion)
	ws.GET("/dummy", s.Dummy)

	return r
}
