// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0

package configuration

import (
	"github.com/stretchr/testify/assert"
	"os"
	"testing"
	"time"
)

func TestWatch(t *testing.T) {

	f, err := os.CreateTemp("", "watch_test")
	if err != nil {
		t.Error(err)
		return
	}

	defer os.Remove(f.Name())

	config := struct {
		Host string `yaml:"Host"`
	}{
		Host: "localhost",
	}

	c := New(config)
	c.SetMnemonic("my-app")
	assert.Equal(t, c.Config().Host, "localhost")

	c.AddFile(f.Name(), Yaml)
	c.Import()

	signal := make(chan bool)

	var h EventHook
	h = &ChangeEventTester{
		callback: func(event ChangeEvent) {
			assert.Equal(t, event.Changlog[0].From, "localhost")
			assert.Equal(t, event.Changlog[0].To, "example.org")
			signal <- true
		},
	}

	c.OnChange(h)

	c.Watch()

	_, err = f.WriteString("Host: example.org")
	if err != nil {
		t.Error(err)
		return
	}

	select {
	case <-signal:
		assert.Equal(t, c.Config().Host, "example.org")
	case <-time.After(time.Second):
		t.Fatalf("Timeout")

	}

}

func TestSettingStopWatching(t *testing.T) {

	f, err := os.CreateTemp("", "watch_test")
	if err != nil {
		t.Error(err)
		return
	}

	defer os.Remove(f.Name())

	config := struct {
		Host string `yaml:"Host"`
	}{
		Host: "localhost",
	}

	c := New(config)
	c.SetMnemonic("my-app")
	assert.Equal(t, c.Config().Host, "localhost")

	c.AddFile(f.Name(), Yaml)
	c.Import().ResetErrors() // Import error is not relevant here

	c.Watch()
	c.StopWatching()

	if c.HasErrors() {
		t.Error(c.Errors())
	}

}

func TestSettingStopWatchingNotOnWatch(t *testing.T) {

	config := struct {
		Host string `yaml:"Host"`
	}{
		Host: "localhost",
	}

	c := New(config)
	c.StopWatching()

	if !c.HasErrors() {
		t.Error("Expected to have an error")
	}

}

func TestSettingStopWatchingTwice(t *testing.T) {

	f, err := os.CreateTemp("", "watch_test")
	if err != nil {
		t.Error(err)
		return
	}

	defer os.Remove(f.Name())

	config := struct {
		Host string `yaml:"Host"`
	}{
		Host: "localhost",
	}

	f.WriteString("Host: example.org")

	c := New(config)
	c.AddFile(f.Name(), Yaml)
	c.Import()
	c.Watch()

	c.StopWatching()
	c.StopWatching()

	e := c.Errors()
	if len(e) != 1 {
		t.Error("Expected to have an error")
	}

	if e[0] != WatchNotRunningError {
		t.Error("Expected to have an error")
	}

}