package config

import (
	"regexp"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/zap/zaptest"
)

func TestConfig(t *testing.T) {
	logger := zaptest.NewLogger(t).Sugar()
	config, err := ReadConfig("test_config.yaml")
	if err != nil {
		assert.FailNowf(t, "Failed to parse config test_config.yaml", err.Error())
	}
	cm := &MainConfigManager{log: logger, Config: *config}

	// Check list of groups
	require.Equal(t, len(cm.Config.Groups), 3, "Checking number of groups")
	assert.Equal(t, "gdb-delphi-dev", cm.Config.DefaultAwsProfile, "AWS profile used by default if no other is specified")
	// Group 1
	requiredConfig1 := &GroupConfig{
		Name:               "Test group 1",
		AllowedRecordTypes: []string{"A"},
		SingleRecords:      []string{"dev-apollo-aurora-cep.cluster-custom-cic9zqsxd2y6.us-east-1.rds.amazonaws.com"},
		Zones: []Zone{
			{Name: "apollo.stream.", RecordFilters: []string{"^jenkins"}},
			{Name: "delphiplatform.io.", RecordFilters: []string{"^slz-api"}}},
	}

	assert.Equal(t, requiredConfig1, cm.Config.Groups[0], "Group 1 check")
	//Group 2
	requiredConfig2 := &GroupConfig{
		Name:               "Test group 2",
		AllowedRecordTypes: []string{"A"},
		Zones:              []Zone{{Name: "apollo.stream.", RecordFilters: []string{"^dsp-api"}}},
	}
	assert.Equal(t, requiredConfig2, cm.Config.Groups[1], "Group 2 check")

	//Group 3
	requiredConfig3 := &GroupConfig{
		Name:               "Test group 3",
		AllowedRecordTypes: []string{"A"},
		Zones:              []Zone{{Name: "delphi.zone.", RecordFilters: []string{"^remote-dev"}, AwsProfile: "gdb-delphi-prod"}},
	}
	assert.Equal(t, requiredConfig3, cm.Config.Groups[2], "Group 3 check")

	// Test admin group functionality, also groupConfig Append as well and setting up default AWS profiles for zones
	require.Equal(t, "Test admins", cm.Config.AdminGroupNames[0], "Admin group name")
	require.Nil(t, cm.Config.AdminGroupConfigs, "Configs should not exist before running GenerateAdminGroups()")
	cm.InitializeManager()
	requiredConfig4 := &GroupConfig{
		Name:               "Test admins",
		AllowedRecordTypes: []string{"A"},
		SingleRecords:      []string{"dev-apollo-aurora-cep.cluster-custom-cic9zqsxd2y6.us-east-1.rds.amazonaws.com"},
		Zones: []Zone{
			{Name: "apollo.stream.", RecordFilters: []string{"^jenkins", "^dsp-api"}, AwsProfile: "gdb-delphi-dev"},
			{Name: "delphiplatform.io.", RecordFilters: []string{"^slz-api"}, AwsProfile: "gdb-delphi-dev"},
			{Name: "delphi.zone.", RecordFilters: []string{"^remote-dev"}, AwsProfile: "gdb-delphi-prod"}},
	}
	assert.Equal(t, requiredConfig4, cm.Config.AdminGroupConfigs[0], "Generated admin group check")
}

func TestGroupConfig(t *testing.T) {
	logger := zaptest.NewLogger(t).Sugar()
	config, err := ReadConfig("test_config.yaml")
	if err != nil {
		assert.FailNowf(t, "Failed to parse config test_config.yaml", err.Error())
	}
	cm := &MainConfigManager{log: logger, Config: *config}
	cm.InitializeManager()

	testGroupManager := &GroupConfigManager{log: logger, Group: cm.Config.Groups[0]}

	assert.True(t, testGroupManager.CheckZonePresense("apollo.stream."), "Is zone in the group config")
	assert.False(t, testGroupManager.CheckZonePresense("none-existing.zone."), "Is zone in the group config")
	groupFilters := []regexp.Regexp{*regexp.MustCompile(`^jenkins\.?apollo\.stream\.`)}
	assert.Equal(t, groupFilters, testGroupManager.GetZoneFilters("apollo.stream."), "Check zone regexps")
	assert.True(t, testGroupManager.CheckRecordType("A"))
	assert.False(t, testGroupManager.CheckRecordType("CNAME"))
	assert.True(t, testGroupManager.CheckRecordName("jenkins.apollo.stream.", "apollo.stream."))
	assert.False(t, testGroupManager.CheckRecordName("apollo.stream.", "apollo.stream."))
	assert.True(t, testGroupManager.CheckRecordName("slz-api.delphiplatform.io.", "delphiplatform.io."))
	assert.False(t, testGroupManager.CheckRecordName("slz-api.delphiplatform.io.", "unknowndomain.io."))
	assert.False(t, testGroupManager.CheckRecordName("not-my-api.delphiplatform.io.", "delphiplatform.io."))
}
