package pilgrim_conf_test

import (
	"os"
	"testing"

	"github.com/stretchr/testify/assert"
	pilgrim_conf "mvvasilev.dev/pilgrim/internal/pilgrim_conf"
)

func test_envVarContext_StringValue(
	t *testing.T,
	envVarKey string,
	getEnvVar func() (value string, isDefined bool),
	expectedVal string,
) {
	os.Setenv(envVarKey, expectedVal)

	val, isDefined := getEnvVar()

	assert.True(t, isDefined)
	assert.Equal(t, expectedVal, val)
}

func Test_envVarContext_Url(t *testing.T) {
	test_envVarContext_StringValue(
		t,
		pilgrim_conf.EnvVarKey_Url,
		func() (string, bool) { return pilgrim_conf.NewEnvVarContext().Url() },
		"driver://user:pass@host:port/segment1/segment2?arg1=val1&arg2=val2",
	)
}

func Test_envVarContext_Driver(t *testing.T) {
	expectedVal := pilgrim_conf.DbDriver_MariaDB

	os.Setenv(pilgrim_conf.EnvVarKey_Driver, string(pilgrim_conf.DbDriver_MariaDB))

	val, isDefined := pilgrim_conf.NewEnvVarContext().Driver()

	assert.True(t, isDefined)
	assert.Equal(t, expectedVal, val)
}

func Test_envVarContext_Username(t *testing.T) {
	test_envVarContext_StringValue(
		t,
		pilgrim_conf.EnvVarKey_Username,
		func() (string, bool) { return pilgrim_conf.NewEnvVarContext().Username() },
		"username",
	)
}

func Test_envVarContext_Password(t *testing.T) {
	test_envVarContext_StringValue(
		t,
		pilgrim_conf.EnvVarKey_Password,
		func() (string, bool) { return pilgrim_conf.NewEnvVarContext().Password() },
		"password",
	)
}

func Test_envVarContext_Host(t *testing.T) {
	test_envVarContext_StringValue(
		t,
		pilgrim_conf.EnvVarKey_Host,
		func() (string, bool) { return pilgrim_conf.NewEnvVarContext().Host() },
		"localhost",
	)
}

func Test_envVarContext_Port(t *testing.T) {
	test_envVarContext_StringValue(
		t,
		pilgrim_conf.EnvVarKey_Port,
		func() (string, bool) { return pilgrim_conf.NewEnvVarContext().Port() },
		"3306",
	)
}

func Test_envVarContext_Directory(t *testing.T) {
	test_envVarContext_StringValue(
		t,
		pilgrim_conf.EnvVarKey_Directory,
		func() (string, bool) { return pilgrim_conf.NewEnvVarContext().Directory() },
		"./custom-directory/migrations",
	)
}

func Test_envVarContext_MigrationTable(t *testing.T) {
	test_envVarContext_StringValue(
		t,
		pilgrim_conf.EnvVarKey_Table,
		func() (string, bool) { return pilgrim_conf.NewEnvVarContext().MigrationTable() },
		"pilgrim_migrations_custom_table",
	)
}

func Test_envVarContext_MigrationTableSchema(t *testing.T) {
	test_envVarContext_StringValue(
		t,
		pilgrim_conf.EnvVarKey_Schema,
		func() (string, bool) { return pilgrim_conf.NewEnvVarContext().MigrationTableSchema() },
		"public",
	)
}

func Test_envVarContext_Segments(t *testing.T) {
	expectedVal := []string{"segment1", "segment2", "segment3"}

	os.Setenv(pilgrim_conf.EnvVarKey_Segments, "segment1/segment2/segment3")

	val, isDefined := pilgrim_conf.NewEnvVarContext().Segments()

	assert.True(t, isDefined)
	assert.Equal(t, expectedVal, val)
}

func Test_envVarContext_Args(t *testing.T) {
	expectedVal := map[string]string{
		"arg1": "val1",
		"arg2": "val2",
		"arg3": "val3",
	}

	os.Setenv(pilgrim_conf.EnvVarKey_Arguments, "arg1=val1&arg2=val2&arg3=val3")

	val, isDefined := pilgrim_conf.NewEnvVarContext().Args()

	assert.True(t, isDefined)
	assert.Equal(t, expectedVal, val)
}