package putsvc

import (
	"context"
	"fmt"

	objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
	objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
	oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
)

// ObjectStorage is an object storage interface.
type ObjectStorage interface {
	// Put must save passed object
	// and return any appeared error.
	Put(context.Context, *objectSDK.Object) error
	// Delete must delete passed objects
	// and return any appeared error.
	Delete(ctx context.Context, tombstone oid.Address, toDelete []oid.ID) error
	// Lock must lock passed objects
	// and return any appeared error.
	Lock(ctx context.Context, locker oid.Address, toLock []oid.ID) error
	// IsLocked must clarify object's lock status.
	IsLocked(context.Context, oid.Address) (bool, error)
}

type localTarget struct {
	storage ObjectStorage
}

func (t localTarget) WriteObject(ctx context.Context, obj *objectSDK.Object, meta objectCore.ContentMeta) error {
	switch meta.Type() {
	case objectSDK.TypeTombstone:
		err := t.storage.Delete(ctx, objectCore.AddressOf(obj), meta.Objects())
		if err != nil {
			return fmt.Errorf("could not delete objects from tombstone locally: %w", err)
		}
	case objectSDK.TypeLock:
		err := t.storage.Lock(ctx, objectCore.AddressOf(obj), meta.Objects())
		if err != nil {
			return fmt.Errorf("could not lock object from lock objects locally: %w", err)
		}
	default:
		// objects that do not change meta storage
	}

	if err := t.storage.Put(ctx, obj); err != nil {
		return fmt.Errorf("(%T) could not put object to local storage: %w", t, err)
	}
	return nil
}