package getsvc

import (
	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
	"go.uber.org/zap"
)

// Option is a Service's constructor option.
type Option func(*Service)

// Service utility serving requests of Object.Get service.
type Service struct {
	log                      *logger.Logger
	localStorage             localStorage
	traverserGenerator       traverserGenerator
	epochSource              epochSource
	keyStore                 keyStorage
	remoteStorageConstructor remoteStorageConstructor
	containerSource          container.Source
}

// New creates, initializes and returns utility serving
// Object.Get service requests.
func New(
	ks keyStorage,
	es epochSource,
	e localStorageEngine,
	tg traverserGenerator,
	cc clientConstructor,
	cs container.Source,
	opts ...Option,
) *Service {
	result := &Service{
		keyStore:    ks,
		epochSource: es,
		log:         logger.NewLoggerWrapper(zap.L()),
		localStorage: &engineLocalStorage{
			engine: e,
		},
		traverserGenerator: tg,
		remoteStorageConstructor: &multiclientRemoteStorageConstructor{
			clientConstructor: cc,
		},
		containerSource: cs,
	}
	for _, option := range opts {
		option(result)
	}
	return result
}

// WithLogger returns option to specify Get service's logger.
func WithLogger(l *logger.Logger) Option {
	return func(s *Service) {
		s.log = l.With(zap.String("component", "Object.Get service"))
	}
}