package operation

import (
	"errors"
	"strconv"
	"sync"
	"time"

	"github.com/seaweedfs/seaweedfs/weed/glog"
)

var ErrorNotFound = errors.New("not found")

type VidInfo struct {
	Locations       []Location
	NextRefreshTime time.Time
}
type VidCache struct {
	sync.RWMutex
	cache map[uint32]VidInfo
}

func (vc *VidCache) Get(vid string) ([]Location, error) {
	id, err := strconv.ParseUint(vid, 10, 32)
	if err != nil {
		glog.V(1).Infof("Unknown volume id %s", vid)
		return nil, err
	}
	if id == 0 {
		return nil, ErrorNotFound
	}
	vc.RLock()
	defer vc.RUnlock()
	info, found := vc.cache[uint32(id)]
	if !found || info.Locations == nil {
		return nil, ErrorNotFound
	}
	if info.NextRefreshTime.Before(time.Now()) {
		return nil, errors.New("expired")
	}
	return info.Locations, nil
}

func (vc *VidCache) Set(vid string, locations []Location, duration time.Duration) {
	id, err := strconv.ParseUint(vid, 10, 32)
	if err != nil {
		glog.V(1).Infof("Unknown volume id %s", vid)
		return
	}
	if id == 0 {
		return
	}
	vc.Lock()
	defer vc.Unlock()
	if vc.cache == nil {
		vc.cache = make(map[uint32]VidInfo)
	}
	vc.cache[uint32(id)] = VidInfo{
		Locations:       locations,
		NextRefreshTime: time.Now().Add(duration),
	}
}
