package ginext

import (
	"context"
	"github.com/gin-gonic/gin"
	"time"
)

type AppContext struct {
	inner      context.Context
	cancelFunc context.CancelFunc
	cancelled  bool
	GinContext *gin.Context
}

func CreateAppContext(g *gin.Context, innerCtx context.Context, cancelFn context.CancelFunc) *AppContext {
	for key, value := range g.Keys {
		innerCtx = context.WithValue(innerCtx, key, value)
	}
	return &AppContext{
		inner:      innerCtx,
		cancelFunc: cancelFn,
		cancelled:  false,
		GinContext: g,
	}
}

func (ac *AppContext) Deadline() (deadline time.Time, ok bool) {
	return ac.inner.Deadline()
}

func (ac *AppContext) Done() <-chan struct{} {
	return ac.inner.Done()
}

func (ac *AppContext) Err() error {
	return ac.inner.Err()
}

func (ac *AppContext) Value(key any) any {
	return ac.inner.Value(key)
}

func (ac *AppContext) Set(key, value any) {
	ac.inner = context.WithValue(ac.inner, key, value)
}

func (ac *AppContext) Cancel() {
	ac.cancelled = true
	ac.cancelFunc()
}

func (ac *AppContext) RequestURI() string {
	if ac.GinContext != nil && ac.GinContext.Request != nil {
		return ac.GinContext.Request.Method + " :: " + ac.GinContext.Request.RequestURI
	} else {
		return ""
	}
}