// package service -- главный объект сервиса
package service

import (
	"context"
	"fmt"
	"log"
	"sync"

	// "git.p78su.freemyip.com/svi/gostore/internal/store_user"
	"git.p78su.freemyip.com/svi/gostore/pkg/serv_http"
	"git.p78su.freemyip.com/svi/gostore/pkg/store"
	"git.p78su.freemyip.com/svi/gostore/pkg/types"
)

// Service -- главный объект сервиса
type Service struct {
	// user     types.IStoreUser
	servHttp types.IServHttp
	// dbMem    types.IStoreMem
	disk     types.IStore
	ctxBg    context.Context // Неотменяемый контекст
	ctx      context.Context // Контекст приложения
	fnCancel func()          // Функция отмены контекста
	wg       *sync.WaitGroup // Ожидатель потоков сервиса
}

// NewService -- возвращает новый объект сервиса
func NewService() (types.IService, error) {
	ctxBg := context.Background()
	ctx, fnCancel := context.WithCancel(ctxBg)
	sf := &Service{
		ctxBg:    ctxBg,
		ctx:      ctx,
		fnCancel: fnCancel,
		wg:       &sync.WaitGroup{},
	}
	var err error
	sf.disk, err = store.NewStore(sf)
	if err != nil {
		return nil, fmt.Errorf("NewService(): in create IStoreDisk, err=\n\t%w", err)
	}
	sf.servHttp, err = serv_http.NewServHttp(sf)
	if err != nil {
		return nil, fmt.Errorf("NewService(): in create IServHttp, err=\n\t%w", err)
	}
	return sf, nil
}

// ServHttp -- возвращает HTTP-сервер
func (sf *Service) ServHttp() types.IServHttp {
	return sf.servHttp
}

// Store -- возвращает хранилище
func (sf *Service) Store() types.IStore {
	return sf.disk
}

// CancelApp -- отменяет контекст приложения
func (sf *Service) CancelApp() {
	sf.fnCancel()
}

// Ctx -- возвращает контекст приложения
func (sf *Service) Ctx() context.Context {
	return sf.ctx
}

// Wg -- возвращает ожидатель группы потоков
func (sf *Service) Wg() *sync.WaitGroup {
	return sf.wg
}

// Run -- запускает сервис в работу
func (sf *Service) Run() {
	go func() {
		err := sf.servHttp.Run()
		if err != nil {
			log.Printf("Service.Run(): in run IServHttp, err=\n\t%v\n", err)
		}
	}()
	sf.wg.Wait()
}
