package kmodule

import (
	"os"
	"testing"
	"time"

	"gitp78su.ipnodns.ru/svi/kern/v2/krn/kctx"
	. "gitp78su.ipnodns.ru/svi/kern/v2/krn/ktypes"
	"gitp78su.ipnodns.ru/svi/kern/v2/mock/mock_env"
)

type tester struct {
	t   *testing.T
	mod IKernelModule
	me  *mock_env.MockEnv
}

func TestKernelModule(t *testing.T) {
	sf := &tester{
		t:  t,
		me: mock_env.MakeEnv(),
	}
	_ = os.Unsetenv("LOCAL_STORE_PATH")
	_ = os.Setenv("LOCAL_STORE_PATH", "/store/store_module")
	_ = os.Unsetenv("LOCAL_HTTP_URL")
	os.Setenv("LOCAL_HTTP_URL", "http://localhost:18331/")
	fnClear := func() {
		pwd := sf.me.Pwd() + "/store/store_module"
		_ = os.RemoveAll(pwd)
	}
	fnClear()
	defer fnClear()
	sf.new()
	sf.run()
	sf.isWork()
	sf.done()
}

// Работа после остановки локальной шины
func (sf *tester) done() {
	sf.t.Log("done")
	kCtx := kctx.GetKernelCtx()

	time.Sleep(time.Millisecond * 250)
	kCtx.Cancel()
	kCtx.Wg().Wait()
	time.Sleep(time.Millisecond * 250)
}

// Проверить признак работы
func (sf *tester) isWork() {
	sf.t.Log("isWork")
	defer func() {
		if _panic := recover(); _panic == nil {
			sf.t.Fatalf("isWork(): panic==nil")
		}
	}()
	_ = sf.mod.IsWork()
}

// Запускает модуль в работу
func (sf *tester) run() {
	sf.t.Log("run")
	defer func() {
		if _panic := recover(); _panic == nil {
			sf.t.Fatalf("run(): panic==nil")
		}
	}()
	mod := sf.mod.(*kModule)
	mod.timePhase.Set(5) // Настройка переменной модуля
	sf.mod.Run()
}

// Создание нового модуля ядра
func (sf *tester) new() {
	sf.t.Log("new")
	sf.newBad1()
	sf.newGood1()
}

func (sf *tester) newGood1() {
	sf.t.Log("newGood1")
	sf.mod = NewKernelModule("test_module")
	if name := sf.mod.Name(); name != "test_module" {
		sf.t.Fatalf("newGood1(): name(%v)!='test_module'", name)
	}
	if ctx := sf.mod.Ctx(); ctx == nil {
		sf.t.Fatalf("newGood1(): ctx==nil")
	}
	if _log := sf.mod.Log(); _log == nil {
		sf.t.Fatalf("newGood1(): log==nil")
	}
	_ = sf.mod.Stat()
	_ = sf.mod.Live()
}

// Нет имени модуля
func (sf *tester) newBad1() {
	sf.t.Log("newBad1")
	defer func() {
		if _panic := recover(); _panic == nil {
			sf.t.Fatalf("newBad1(): panic==nil")
		}
	}()
	_ = NewKernelModule("")
}
