package applicationservice

import (
	"sync"

	"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
	"bitbucket.org/nemt/nemt-portal-api/application/notificationservice"
	"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi"
	"bitbucket.org/nemt/nemt-portal-api/domain/service"
	"bitbucket.org/nemt/nemt-portal-api/infra/config"
)

var (
	instance *Service
	once     sync.Once
)

// Service holds the domain service repositories
type Service struct {
	Users         *userService
	Rides         *rideService
	Visits        *visitService
	Provider      *providerService
	Notification  *notificationService
	Profile       *profileService
	Organization  *organizationService
	Zipcodes      *zipcodeService
	Plan          *planService
	PasswordReset *passwordResetService
}

// New returns a new domain Service instance
func New(svc *service.Service, mapper *entitymapping.Mapper, notification *notificationservice.Service, cfg *config.Config) *Service {
	once.Do(func() {
		bcbsi := bcbsi.New(cfg)

		instance = &Service{
			Users:         newUserService(svc, mapper, bcbsi, cfg),
			Rides:         newRideService(svc, mapper),
			Visits:        newVisitService(svc, mapper),
			Provider:      newProviderService(svc, mapper),
			Notification:  newNotificationService(svc, mapper, notification, cfg),
			Profile:       newProfileService(svc, mapper),
			Organization:  newOrganizationService(svc, mapper),
			Zipcodes:      newZipcodeService(svc, mapper),
			Plan:          newPlanService(svc, mapper),
			PasswordReset: newPasswordResetService(svc, mapper),
		}
	})

	return instance
}
