//go:build !runOnTask

// Copyright 2023 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package jobqueue

import (
	"github.com/stretchr/testify/assert"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"runtime"
	"testing"
	"time"
)

func TestWriteToDB2(t *testing.T) {
	gormDB, err := gorm.Open(sqlite.Open("file:unique_id?mode=memory&cache=shared"), &gorm.Config{})
	if err != nil {
		t.Fatalf("a error occurred while opening the database: %v", err)
	}
	t.Cleanup(func() {
		sqlDB, err := gormDB.DB()
		if err != nil {
			t.Fatalf("failed to get generic database object from GORM DB: %v", err)
		}
		_ = sqlDB.Close()
	})

	gormDB.Logger = gormDB.Logger.LogMode(4)
	manager := &Manager{database: gormDB}

	// Starte den DBSaver
	NewJobSyncer(manager)

	db := gormDB
	mgr := NewManager()
	mgr.SetDB(gormDB)

	worker := NewLocalWorker(1)
	err = mgr.AddWorker(worker)
	assert.Nil(t, err)

	err = mgr.Start()
	assert.Nil(t, err)

	runner := &CounterRunnable{}
	job := NewJob[CounterResult]("job1", runner)

	scheduler := &InstantScheduler{}
	err = mgr.ScheduleJob(job, scheduler)
	assert.Nil(t, err)
	_ = manager.WaitSync()

	err = mgr.CancelJobSchedule("job1")
	assert.Nil(t, err)
	_ = manager.WaitSync()

	//	time.Sleep(1 * time.Second)

	scheduler2 := &InstantScheduler{}
	err = mgr.ScheduleJob(job, scheduler2)
	assert.Nil(t, err)
	_ = manager.WaitSync()

	err = mgr.CancelJobSchedule("job1")
	assert.Nil(t, err)

	//	time.Sleep(1 * time.Second)

	scheduler3 := &InstantScheduler{}
	err = mgr.ScheduleJob(job, scheduler3)
	assert.Nil(t, err)
	_ = manager.WaitSync()

	//	time.Sleep(1 * time.Second)

	if mgr.jobSyncer == nil {
		t.Error("mgr.JobSyncer == nil")
		return
	}

	//	time.Sleep(1 * time.Second)

	_ = mgr.jobSyncer.Sync(job)
	_ = manager.WaitSync()

	runtime.Gosched()
	//	time.Sleep(1 * time.Second)
	err = mgr.CancelJobSchedule("job1")
	assert.Nil(t, err)

	runtime.Gosched()
	//	time.Sleep(1 * time.Second)
	_ = manager.WaitSync()

	scheduler4 := &InstantScheduler{}
	err = mgr.ScheduleJob(job, scheduler4)
	assert.Nil(t, err)
	_ = manager.WaitSync()

	runtime.Gosched()
	//time.Sleep(1 * time.Second)

	_ = mgr.jobSyncer.Sync(job)
	_ = manager.WaitSync()

	//time.Sleep(2 * time.Second)
	err = mgr.CancelJobSchedule("job1")
	assert.Nil(t, err)
	_ = manager.WaitSync()

	tries := 10
	for tries > 0 {

		var tmpJob JobPersistence
		if err := db.First(&tmpJob, "id = ?", "job1").Error; err == nil {
			break
		}
		tries--
		time.Sleep(1 * time.Second)

	}

	assert.True(t, tries > 0)

	time.Sleep(1 * time.Second)
	err = LoadJobsAndScheduleFromDatabase(db, mgr)
	assert.Nil(t, err)
	_ = manager.WaitSync()
	time.Sleep(1 * time.Second)

}