package service

import (
	"sync"

	"bitbucket.org/nemt/nemt-portal-api/domain/contract"
	"bitbucket.org/nemt/nemt-portal-api/infra/config"
	"bitbucket.org/nemt/nemt-portal-api/infra/logger"
)

var (
	instance *Service
	once     sync.Once
)

// Service holds the domain service repositories
type Service struct {
	db            contract.DataManager
	cache         contract.CacheManager
	tnc           contract.TNCManager
	Users         *userService
	Rides         *rideService
	Visits        *visitService
	Provider      *providerService
	Notification  *notificationService
	Profile       *profileService
	Organization  *organizationService
	Zipcodes      *zipcodeService
	Plans         *planService
	PasswordReset *passwordResetService
}

// New returns a new domain Service instance
func New(db contract.DataManager, cache contract.CacheManager, cfg *config.Config, log *logger.Logger) (*Service, error) {
	once.Do(func() {
		instance = &Service{db: db, cache: cache}

		instance.Users = newUserService(instance)
		instance.Rides = newRideService(instance)
		instance.Visits = newVisitService(instance)
		instance.Provider = newProviderService(instance)
		instance.Notification = newNotificationService(instance)
		instance.Profile = newProfileService(instance)
		instance.Organization = newOrganizationService(instance)
		instance.Zipcodes = newZipcodeService(instance)
		instance.Plans = newPlanService(instance)
		instance.PasswordReset = newPasswordResetService(instance)
	})

	return instance, nil
}
