package writecache

import (
	"bytes"
	"errors"
	"fmt"
	"strings"

	"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/schema/common"
	cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
	oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
	"github.com/mr-tron/base58"
)

var WritecacheParser = common.WithFallback(
	DefaultBucketParser,
	common.RawParser.ToFallbackParser(),
)

func DefaultBucketParser(key, value []byte) (common.SchemaEntry, common.Parser, error) {
	if value != nil {
		return nil, nil, errors.New("not a bucket")
	}
	if !bytes.Equal(key, []byte{0}) {
		return nil, nil, errors.New("invalid key")
	}
	return &DefaultBucket{}, DefaultRecordParser, nil
}

func DefaultRecordParser(key, value []byte) (common.SchemaEntry, common.Parser, error) {
	parts := strings.Split(string(key), "/")

	if len(parts) != 2 {
		return nil, nil, errors.New("invalid key, expected address string <CID>/<OID>")
	}

	cnrRaw, err := base58.Decode(parts[0])
	if err != nil {
		return nil, nil, errors.New("can't decode CID string")
	}
	objRaw, err := base58.Decode(parts[1])
	if err != nil {
		return nil, nil, errors.New("can't decode OID string")
	}

	cnr := cid.ID{}
	if err := cnr.Decode(cnrRaw); err != nil {
		return nil, nil, fmt.Errorf("can't decode CID: %w", err)
	}
	obj := oid.ID{}
	if err := obj.Decode(objRaw); err != nil {
		return nil, nil, fmt.Errorf("can't decode OID: %w", err)
	}

	var r DefaultRecord

	r.addr.SetContainer(cnr)
	r.addr.SetObject(obj)

	r.data = value[:]

	return &r, nil, nil
}