package router

// |@@| C

import (
	"gardening/src/lib/config"
	"gardening/src/lib/dev_tool"
	"gardening/src/lib/maestro"
	"github.com/gin-gonic/gin"
	"reflect"
	"strings"
	"time"
)

type MaeMiddleware struct {
	Config  *config.Config
	DevTool *dev_tool.DevTool
}

func (this *MaeMiddleware) Act(act func(*gin.Context) (maestro.MaeIn, maestro.MaeOut), route interface{}) gin.HandlerFunc {
	return func(c *gin.Context) {
		if !this.Config.IsDevEnv() {
			act(c)
			return
		}

		start := time.Now()
		maeIn, maeOut := act(c)
		elapsed := time.Since(start)

		record := this.DevTool.GetCurrentRecord(c)

		this.extractRouteInfo(record.RouteInfo, route, c)
		this.extractMaeInfo(record.RouteInfo, maeIn, maeOut)
		record.RouteInfo.Duration = elapsed.String()

		return
	}
}

func (this *MaeMiddleware) getStructName(structure interface{}) string {
	s := reflect.TypeOf(structure).String()
	ss := strings.Split(s, ".")
	if len(ss) != 2 {
		return ""
	}
	return ss[1]
}

func (this *MaeMiddleware) extractMaeInfo(info *dev_tool.RouteInfo, in maestro.MaeIn, out maestro.MaeOut) {
	info.MaeIn = this.getStructName(in)
	if out != nil {
		info.MaeOut = this.getStructName(out)
	}
	if info.MaeIn == "" {
		// Mae is always matching the MaeIn
		info.Mae = strings.TrimSuffix(info.MaeIn, "In")
	}
}

func (this *MaeMiddleware) extractRouteInfo(info *dev_tool.RouteInfo, route interface{}, c *gin.Context) {
	info.Route = this.getStructName(route)
	info.RouteUrl = c.FullPath()
	info.RouteMethod = c.Request.Method
}
