package native

import (
	"context"
	"sync"
	"time"

	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
)

const networkCacheTTL = time.Minute

var networkInfoCache = &networkInfoCacheT{}

type networkInfoCacheT struct {
	guard   sync.RWMutex
	current *netmap.NetworkInfo
	fetchTS time.Time
}

func (c *networkInfoCacheT) getOrFetch(ctx context.Context, cli *client.Client) (*netmap.NetworkInfo, error) {
	if v := c.get(); v != nil {
		return v, nil
	}
	return c.fetch(ctx, cli)
}

func (c *networkInfoCacheT) get() *netmap.NetworkInfo {
	c.guard.RLock()
	defer c.guard.RUnlock()

	if c.current == nil || time.Since(c.fetchTS) > networkCacheTTL {
		return nil
	}

	return c.current
}

func (c *networkInfoCacheT) fetch(ctx context.Context, cli *client.Client) (*netmap.NetworkInfo, error) {
	c.guard.Lock()
	defer c.guard.Unlock()

	if time.Since(c.fetchTS) <= networkCacheTTL {
		return c.current, nil
	}

	res, err := cli.NetworkInfo(ctx, client.PrmNetworkInfo{})
	if err != nil {
		return nil, err
	}

	v := res.Info()
	c.current = &v
	c.fetchTS = time.Now()

	return c.current, nil
}