package archive

import (
	"context"
	"fmt"
	"path"

	"git.kmsign.ru/royalcat/tstor/server/src/daemon"
	"git.kmsign.ru/royalcat/tstor/server/src/vfs"
	"git.kmsign.ru/royalcat/tstor/server/tstor"
	"github.com/hashicorp/golang-lru/arc/v2"
	"github.com/knadh/koanf/v2"
	"go.opentelemetry.io/otel"
)

const DaemonName string = "archive"

var Plugin = &tstor.Plugin{
	Name:              DaemonName,
	DaemonConstructor: NewDaemon,
}

var _ daemon.DaemonConstructor = NewDaemon

func NewDaemon(ctx context.Context, koanf *koanf.Koanf) (daemon.Daemon, error) {
	return &Daemon{}, nil
}

var tracer = otel.Tracer("git.kmsign.ru/royalcat/tstor/plugins/archive")

var _ daemon.Daemon = (*Daemon)(nil)

type Daemon struct {
	blockcache *arc.ARCCache[blockIndex, block]
}

// Name implements daemon.Daemon.
func (d *Daemon) Name() string {
	return DaemonName
}

// Extensions implements daemon.Daemon.
func (d *Daemon) Extensions() []string {
	return []string{".zip", ".rar", ".7z"}
}

// GetFS implements daemon.Daemon.
func (d *Daemon) GetFS(ctx context.Context, sourcePath string, file vfs.File) (vfs.Filesystem, error) {
	ext := path.Ext(sourcePath)

	stat, err := file.Info()
	if err != nil {
		return nil, err
	}

	switch ext {
	case ".zip":
		return d.NewArchiveFS(ctx, sourcePath, stat.Name(), file, stat.Size(), d.ZipLoader)
	case ".rar":
		return d.NewArchiveFS(ctx, sourcePath, stat.Name(), file, stat.Size(), d.RarLoader)
	case ".7z":
		return d.NewArchiveFS(ctx, sourcePath, stat.Name(), file, stat.Size(), d.SevenZipLoader)
	}

	return nil, fmt.Errorf("unknown archive type")
}

// Close implements daemon.Daemon.
func (d *Daemon) Close(ctx context.Context) error {
	panic("unimplemented")
}