package storage

import (
	"context"
	"errors"
	"kra/internal/biz/system"
	"path"
	"strings"
)

func deletePrefixViaList(ctx context.Context, prefix string, list func(context.Context, string, string, int) ([]*system.StoredFile, string, bool, error), remove func(context.Context, string) error) error {
	prefix, err := normalizeDeletePrefix(prefix)
	if err != nil {
		return err
	}
	cursor := ""
	for {
		items, next, more, err := list(ctx, prefix+"/", cursor, 1000)
		if err != nil {
			return err
		}
		for _, item := range items {
			if err := remove(ctx, item.Path); err != nil {
				return err
			}
		}
		if !more {
			return nil
		}
		cursor, err = advanceDeletePrefixCursor(cursor, next, more)
		if err != nil {
			return err
		}
	}
}

// normalizeDeletePrefix rejects requests that could accidentally target the
// storage root and returns the canonical key form used by all backends.
func normalizeDeletePrefix(prefix string) (string, error) {
	prefix = strings.TrimSpace(strings.ReplaceAll(prefix, "\\", "/"))
	prefix = strings.Trim(prefix, "/")
	if prefix == "" {
		return "", errors.New("storage delete prefix is required")
	}
	for _, part := range strings.Split(prefix, "/") {
		if part == ".." {
			return "", errors.New("invalid storage delete prefix")
		}
	}
	clean := path.Clean(prefix)
	if clean == "." || clean == ".." || strings.HasPrefix(clean, "../") {
		return "", errors.New("invalid storage delete prefix")
	}
	return clean, nil
}

// advanceDeletePrefixCursor prevents a backend that reports a truncated page
// without a new cursor from making DeletePrefix loop forever.
func advanceDeletePrefixCursor(current, next string, more bool) (string, error) {
	if !more {
		return "", nil
	}
	current = strings.TrimSpace(current)
	next = strings.TrimSpace(next)
	if next == "" || next == current {
		return "", errors.New("storage delete prefix pagination made no progress")
	}
	return next, nil
}

func boundedPrefix(key, prefix string) string {
	if strings.HasSuffix(strings.ReplaceAll(prefix, "\\", "/"), "/") && !strings.HasSuffix(key, "/") {
		return key + "/"
	}
	return key
}
