// Package kernel -- объект ядра прилоэжения
//
//	Содержит базовый функционал сервиса
package kernel

import (
	"context"
	"fmt"
	"sync"
	// "time"

	"wartank/pkg/components/kernel/keeper"
	"wartank/pkg/components/kernel/slog"
	"wartank/pkg/components/kernel/wgname"
	"wartank/pkg/types"
)

/*
	Базовый объект приложения.
*/

// Kernel -- объект ядра приложения
type Kernel struct {
	ctxBg    context.Context // Неотменяемый контекст приложения
	ctxApp   context.Context // Отменяемый контекст приложения
	fnCancel func()          // Функция отмены приложения
	keeper   *keeper.Keeper  // Сторож системных сигналов
	slog     *slog.Slog      // Логгер в два вывода
	wg       *wgname.WgName  // Групповое ожидание частей приложения
	block    sync.Mutex
}

// NewKernel -- возвращает новый *Kernel
func NewKernel() (sf *Kernel, err error) {
	// timeStart := time.Now().UTC().Format("2006-10-02 15:04:05.000")
	// fmt._rintf("%v\t%v\tCI/CD test\n", cons.SelfName, timeStart)
	sf = &Kernel{
		ctxBg: context.Background(),
		wg:    wgname.NewWgName(),
	}
	sf.ctxApp, sf.fnCancel = context.WithCancel(sf.ctxBg)
	sf.block.Lock()
	sf.slog, err = slog.NewSlog(sf)
	sf.block.Unlock()
	if err != nil {
		return nil, fmt.Errorf("NewKernel(): in creste ISlog, err=%w", err)
	}
	sf.slog.Debugf("NewKernel()")
	sf.keeper = keeper.NewKeeper(sf)
	return sf, nil
}

// Wg -- возвращает объект групповой сихнронизации
func (sf *Kernel) Wg() types.IWgName {
	return sf.wg
}

// CtxApp -- возвращает глобальный контекст приложения
func (sf *Kernel) CtxApp() context.Context {
	return sf.ctxApp
}

// Done -- возвращает канал отмены контекста приложения
func (sf *Kernel) Done() <-chan struct{} {
	return sf.ctxApp.Done()
}

// CancelApp -- отменяет глобальный контекст приложения
func (sf *Kernel) CancelApp() {
	sf.block.Lock()
	defer sf.block.Unlock()
	sf.slog.Infof("Kernel.CancelApp()\n")
	sf.fnCancel()
}

// Slog -- возвращает глобальный лог приложения
func (sf *Kernel) Slog() types.ISlog {
	return sf.slog
}
