package torrent

import (
	"context"
	"path/filepath"

	"github.com/anacrolix/torrent"
	"github.com/anacrolix/torrent/types/infohash"
	"github.com/royalcat/kv"
)

func newFileMappingsStore(metaDir string, storage TorrentFileDeleter) (*filesMappingsStore, error) {
	str, err := kv.NewBadgerKVBytes[string, string](filepath.Join(metaDir, "file-mappings"))
	if err != nil {
		return nil, err
	}

	r := &filesMappingsStore{
		mappings: str,
		storage:  storage,
	}

	return r, nil
}

type filesMappingsStore struct {
	mappings kv.Store[string, string]
	storage  TorrentFileDeleter
}

type TorrentFileDeleter interface {
	DeleteFile(file *torrent.File) error
}

func fileKey(file *torrent.File) string {
	return file.Torrent().InfoHash().HexString() + "/" + file.Path()
}

func (r *filesMappingsStore) MapFile(ctx context.Context, file *torrent.File, target string) error {
	return r.mappings.Set(ctx, fileKey(file), target)
}

func (r *filesMappingsStore) ExcludeFile(ctx context.Context, file *torrent.File) error {
	return r.mappings.Set(ctx, fileKey(file), "")
}

func (r *filesMappingsStore) FileMappings(ctx context.Context, ih infohash.T) (map[string]string, error) {
	out := map[string]string{}
	err := r.mappings.RangeWithPrefix(ctx, ih.HexString(), func(k, v string) bool {
		out[k] = v
		return true
	})
	return out, err
}

func (r *filesMappingsStore) Close(ctx context.Context) error {
	return r.mappings.Close(ctx)
}