package sessions

import (
	"intent-system/pkg/itypes"
	"intent-system/pkg/middleware"
	"intent-system/pkg/storage"
	"sync"

	"github.com/civet148/log"
	"github.com/gin-gonic/gin"
)

var locker sync.RWMutex
var contexts = make(map[string]*itypes.Context, 0)

func init() {
	preloadContexts()
}

func NewContext(s *itypes.Session) *itypes.Context {
	ctx := &itypes.Context{
		Session: &itypes.Session{
			UserId:      s.UserId,
			UserName:    s.UserName,
			Email:       s.Email,
			Alias:       s.Alias,
			PhoneNumber: s.PhoneNumber,
			IsAdmin:     s.IsAdmin,
			LoginIP:     s.LoginIP,
			AuthToken:   s.AuthToken,
			LoginMode:   s.LoginMode,
		},
	}
	locker.Lock()
	defer locker.Unlock()
	contexts[s.AuthToken] = ctx
	putLevelDB(ctx)
	return ctx
}

func RemoveContext(c *gin.Context) *itypes.Context {
	strToken := middleware.GetAuthToken(c)
	locker.Lock()
	defer locker.Unlock()
	for k, v := range contexts {
		if v.AuthToken() == strToken {
			delete(contexts, k)
			deleteLevelDB(k)
			return v
		}
	}
	return nil
}

func GetContext(c *gin.Context) *itypes.Context {
	strToken := middleware.GetAuthToken(c)
	locker.RLock()
	defer locker.RUnlock()
	v, ok := contexts[strToken]
	if ok && v != nil {
		return v
	}
	return nil
}

func putLevelDB(ctx *itypes.Context) {
	if err := storage.Store.PutContext(ctx); err != nil {
		log.Errorf("level db put error [%s]", err)
		return
	}
}

func deleteLevelDB(strAuthToken string) {
	storage.Store.DeleteContext(strAuthToken)
}

func preloadContexts() {
	var err error
	locker.Lock()
	defer locker.Unlock()
	if contexts, err = storage.Store.LoadContexts(); err != nil {
		log.Errorf(err.Error())
	}
}
