package services

import (
	"git.aiterp.net/rpdata/api/database"
	"git.aiterp.net/rpdata/api/services/loaders"
	"git.aiterp.net/rpdata/api/space"
)

// A Bundle contains all services.
type Bundle struct {
	Tags       *TagService
	Characters *CharacterService
	Changes    *ChangeService
	Logs       *LogService
	Channels   *ChannelService
	Stories    *StoryService
	Auth       *AuthService
	Files      *FileService
}

// NewBundle creates a new bundle.
func NewBundle(db database.Database, spaceClient *space.Client) *Bundle {
	bundle := &Bundle{}
	bundle.Auth = &AuthService{
		keys:  db.Keys(),
		users: db.Users(),
	}
	bundle.Changes = &ChangeService{
		changes:     db.Changes(),
		authService: bundle.Auth,
	}
	bundle.Files = &FileService{
		files:         db.Files(),
		authService:   bundle.Auth,
		changeService: bundle.Changes,
		space:         spaceClient,
	}
	bundle.Tags = &TagService{tags: db.Tags()}
	bundle.Characters = &CharacterService{
		characters:    db.Characters(),
		loader:        loaders.CharacterLoaderFromRepository(db.Characters()),
		changeService: bundle.Changes,
		authService:   bundle.Auth,
	}
	bundle.Channels = &ChannelService{
		channels:      db.Channels(),
		loader:        loaders.ChannelLoaderFromRepository(db.Channels()),
		changeService: bundle.Changes,
		authService:   bundle.Auth,
	}
	bundle.Logs = &LogService{
		logs:             db.Logs(),
		posts:            db.Posts(),
		changeService:    bundle.Changes,
		channelService:   bundle.Channels,
		characterService: bundle.Characters,
		authService:      bundle.Auth,

		unknownNicks: make(map[string]int, 512),
	}
	bundle.Stories = &StoryService{
		stories:          db.Stories(),
		chapters:         db.Chapters(),
		comments:         db.Comments(),
		changeService:    bundle.Changes,
		characterService: bundle.Characters,
		authService:      bundle.Auth,
	}

	bundle.Characters.logService = bundle.Logs

	return bundle
}