package config

import (
	"os"
	"testing"

	"github.com/stretchr/testify/assert"
)

var testGRPC = &GRPC{
	Port: "5050",
}

var testREST = &REST{
	ExternalPort: "5051",
}

var testGRPCNil = &GRPC{
	Port: "",
}

var testRESTNil = &REST{
	ExternalPort: "",
}

var testInspector = &Inspector{
	InspectorURL: "fake.url",
}

var testLogger = &Logger{
	Level:  "info",
	Output: "json",
	Format: "stderr",
}

var testMonitor = &Monitor{
	Address: "5053",
}

var testExtraAttributes = &ExtraAttributes{
	MonitorMode: "false",
}

var testFilter = &Filter{
	AllowList: map[string]string{"21": "testy/test"},
	DenyList: map[string]string{"26": "foo/bar"},
}

var testConfig = &Config{
	*testGRPC,
	*testREST,
	*testLogger,
	*testMonitor,
	*testInspector,
	*testExtraAttributes,
	*testFilter,
}

// https://yourbasic.org/golang/gotcha-why-nil-error-not-equal-nil/
// Assigns untyped nil
func AssignNil() (err error) {
	return
}

func TestLoadConfig(t *testing.T) {
	t.Run("Testing with correct file path", func(t *testing.T) {

		got := testConfig.LoadConfig("../../config/config.toml.example")

		want := AssignNil()

		assert.Equal(t, got, want)
	})

	t.Run("Testing with incorrect file path", func(t *testing.T) {
		err := testConfig.LoadConfig("../foo/bar.toml")

		assert.EqualErrorf(t, err, err.Error(), "reading config file :%w")
	})
}

func TestValidateConfig(t *testing.T) {
	t.Run("Testing with valid GRPC & REST ports", func(t *testing.T) {
		got := ValidateConfig(testConfig)

		want := AssignNil()

		assert.Equal(t, got, want)
	})

	t.Run("Testing with invalid GRPC port", func(t *testing.T) {
		testConfig := &Config{
			*testGRPCNil,
			*testREST,
			*testLogger,
			*testMonitor,
			*testInspector,
			*testExtraAttributes,
			*testFilter,
		}
		err := ValidateConfig(testConfig)
		assert.EqualErrorf(t, err, err.Error(), "invalid TCP port for gRPC server: '%s'")
	})

	t.Run("Testing with invalid REST port", func(t *testing.T) {
		testConfig := &Config{
			*testGRPC,
			*testRESTNil,
			*testLogger,
			*testMonitor,
			*testInspector,
			*testExtraAttributes,
			*testFilter,
		}
		err := ValidateConfig(testConfig)
		assert.EqualErrorf(t, err, err.Error(), "invalid TCP port for HTTP gateway: '%s'")
	})

	t.Run("Testing with filled allowlist & denylist", func(t *testing.T) {
		testConfig := &Config{
			*testGRPC,
			*testRESTNil,
			*testLogger,
			*testMonitor,
			*testInspector,
			*testExtraAttributes,
			*testFilter,
		}
		err := ValidateConfig(testConfig)
		assert.EqualErrorf(t, err, err.Error(), "Both allowlist & denylist cannot have items at the same time")
	})

}

func TestRunConfig(t *testing.T) {
	t.Run("Testing correct running configuration", func(t *testing.T) {
		os.Chdir("../../")
		got, errGot := RunConfigWithConfigFile("config/config.toml.example")

		want, errWant := testConfig, AssignNil()

		assert.Equal(t, got, want)
		assert.Equal(t, errGot, errWant)
	})
}
