package searchsvc

import (
	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
	cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
	objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
	oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
	"go.uber.org/zap"
)

type execCtx struct {
	svc *Service

	prm Prm

	log *logger.Logger

	curProcEpoch uint64
}

func (exec *execCtx) setLogger(l *logger.Logger) {
	exec.log = &logger.Logger{Logger: l.With(
		zap.String("request", "SEARCH"),
		zap.Stringer("container", exec.containerID()),
		zap.Bool("local", exec.isLocal()),
		zap.Bool("with session", exec.prm.common.SessionToken() != nil),
		zap.Bool("with bearer", exec.prm.common.BearerToken() != nil),
	)}
}

func (exec execCtx) isLocal() bool {
	return exec.prm.common.LocalOnly()
}

func (exec *execCtx) containerID() cid.ID {
	return exec.prm.cnr
}

func (exec *execCtx) searchFilters() objectSDK.SearchFilters {
	return exec.prm.filters
}

func (exec *execCtx) netmapEpoch() uint64 {
	return exec.prm.common.NetmapEpoch()
}

func (exec *execCtx) netmapLookupDepth() uint64 {
	return exec.prm.common.NetmapLookupDepth()
}

func (exec *execCtx) initEpoch() error {
	exec.curProcEpoch = exec.netmapEpoch()
	if exec.curProcEpoch > 0 {
		return nil
	}

	e, err := exec.svc.currentEpochReceiver.Epoch()
	if err != nil {
		return err
	}

	exec.curProcEpoch = e
	return nil
}

func (exec *execCtx) writeIDList(ids []oid.ID) error {
	ids = exec.filterAllowedObjectIDs(ids)
	return exec.prm.writer.WriteIDs(ids)
}

func (exec *execCtx) filterAllowedObjectIDs(objIDs []oid.ID) []oid.ID {
	sessionToken := exec.prm.common.SessionToken()
	if sessionToken == nil {
		return objIDs
	}
	result := make([]oid.ID, 0, len(objIDs))
	for _, objID := range objIDs {
		if sessionToken.AssertObject(objID) {
			result = append(result, objID)
		}
	}
	return result
}