package thumbnail

import (
	"mime"
	"path/filepath"

	lru "github.com/hashicorp/golang-lru"
)

type CachingThumbnailer struct {
	t     Thumbnailer
	cache *lru.Cache // threadsafe, might be nil
}

var _ Thumbnailer = &CachingThumbnailer{} // interface assertion

func NewCachingThumbnailer(cacheSize int, opts *Config) (Thumbnailer, error) {

	upstream := NewThumbnailerEx(opts)

	if cacheSize == 0 {
		return upstream, nil
	}

	thumbCache, err := lru.New(cacheSize)
	if err != nil {
		return nil, err
	}

	return &CachingThumbnailer{
		t:     upstream,
		cache: thumbCache,
	}, nil
}

func (this *CachingThumbnailer) RenderFile(absPath string) ([]byte, error) {
	mimeType := mime.TypeByExtension(filepath.Ext(absPath))
	return this.RenderFileAs(absPath, mimeType)
}

func (this *CachingThumbnailer) RenderFileAs(absPath, mimeType string) ([]byte, error) {
	thumb, ok := this.cache.Get(absPath)
	if ok {
		return thumb.([]byte), nil
	}

	// Add to cache
	rendered, err := this.t.RenderFile(absPath)
	if err != nil {
		return nil, err
	}

	this.cache.Add(absPath, rendered)

	return rendered, nil
}
