package storage

import (
	"os"
	"path"
	"time"

	cache "github.com/patrickmn/go-cache"
)

type Cache struct {
	db   *cache.Cache
	path string
}

func NewCache(path ...string) (*Cache, error) {
	var err error = nil
	c := &Cache{db: cache.New(0, time.Minute*15), path: ""}
	if len(path) != 0 {
		c.path = path[0]
		if _, err := os.Stat(c.path); err == nil {
			err = c.db.LoadFile(c.path)
		}
	}
	return c, err
}

func (c *Cache) List(ns []string, limits ...string) ([]string, error) {
	namespace := resolveNamespace(ns)
	limits = resolveLimits(limits)
	limits[0] = path.Join(namespace, limits[0])
	limits[1] = path.Join(namespace, limits[1])
	m := c.db.Items()
	keys := []string{}
	for k := range m {
		if k >= limits[0] && k <= limits[1] {
			keys = append(keys, k)
		}
	}
	return keys, nil
}

func (c *Cache) Get(key string, ns ...string) ([]byte, error) {
	namespace := resolveNamespace(ns)
	v, ok := c.db.Get(path.Join(namespace, key))
	if !ok {
		return nil, ErrNotFound
	}
	b, ok := v.([]byte)
	if !ok {
		return nil, ErrNotImpl
	}
	return b, nil
}

func (c *Cache) Set(key string, value []byte, ns ...string) error {
	namespace := resolveNamespace(ns)
	c.db.Set(path.Join(namespace, key), value, 0)
	return nil
}

func (c *Cache) Close() error {
	if c.path != "" {
		return c.db.SaveFile(c.path)
	}
	return nil
}
