// package app -- главный объект приложения
package kernel

import (
	"context"
	"fmt"

	"p78git.ddns.net/svi/libtui/lib/cursor"
	"p78git.ddns.net/svi/libtui/lib/screen"
	"p78git.ddns.net/svi/libtui/types"
)

// Kernel -- объектприложения
type Kernel struct {
	screen   types.IScreen   // Объект приложения
	cursor   types.ICursor   // Глобальный курсор
	ctxBg    context.Context // Неотменяемый контекст ядра
	ctx      context.Context // Контекст ядра
	fnCancel func()
}

// NewKernel -- возвращает новый объект приложения
func NewKernel() (*Kernel, error) {
	ctxBg := context.Background()
	ctx, fnCancel := context.WithCancel(ctxBg)
	sf := &Kernel{
		ctxBg:    ctxBg,
		ctx:      ctx,
		fnCancel: fnCancel,
	}
	var err error
	sf.screen, err = screen.NewScreen(sf)
	if err != nil {
		return nil, fmt.Errorf("NewKernel(): i create IScreen, err=\n\t%w", err)
	}
	sf.cursor, err = cursor.NewCursor(sf)
	if err != nil {
		return nil, fmt.Errorf("NewKernel(): in create ICursor, err=\n\t%w", err)
	}
	return sf, nil
}

// Screen -- возвращает объект экрана
func (sf *Kernel) Screen() types.IScreen {
	return sf.screen
}

// Cursor -- возвращает курсор экрана
func (sf *Kernel) Cursor() types.ICursor {
	return sf.cursor
}

// Run -- запускает объект приложения в работу
func (sf *Kernel) Run() error {
	<-sf.ctx.Done()
	go sf.screen.Run()
	return nil
}

// CancelApp -- отменяет глобальный онтекст приложения
func (sf *Kernel) CancelApp() {
	sf.fnCancel()
}

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