package agent

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/module/modagentk"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/pkg/agentcfg"
	"go.uber.org/mock/gomock"
)

var (
	testSupportedCRD = requiredFluxCRDs[0]
)

var (
	_ modagentk.Module = &module{}
)

func TestModule_DefaultAndValidateConfiguration_WithoutFluxConfig(t *testing.T) {
	// GIVEN
	m := &module{}
	cfg := &agentcfg.AgentConfiguration{}

	// WHEN
	err := m.DefaultAndValidateConfiguration(cfg)

	// THEN
	require.NoError(t, err)
	assert.Equal(t, defaultServiceAPIBaseURL, cfg.Flux.WebhookReceiverUrl)
}

func TestModule_DefaultAndValidateConfiguration_WithoutWebhookReceiverUrlConfig(t *testing.T) {
	// GIVEN
	m := &module{}
	cfg := &agentcfg.AgentConfiguration{
		Flux: &agentcfg.FluxCF{},
	}

	// WHEN
	err := m.DefaultAndValidateConfiguration(cfg)

	// THEN
	require.NoError(t, err)
	assert.Equal(t, defaultServiceAPIBaseURL, cfg.Flux.WebhookReceiverUrl)
}

func TestModule_DefaultAndValidateConfiguration_WithWebhookReceiverUrlConfig(t *testing.T) {
	// GIVEN
	m := &module{}
	cfg := &agentcfg.AgentConfiguration{
		Flux: &agentcfg.FluxCF{
			WebhookReceiverUrl: "https://example.com",
		},
	}

	// WHEN
	err := m.DefaultAndValidateConfiguration(cfg)

	// THEN
	require.NoError(t, err)
	assert.Equal(t, "https://example.com", cfg.Flux.WebhookReceiverUrl)
}

func TestModule_DefaultAndValidateConfiguration_WithDefaultEnabledFluxModule(t *testing.T) {
	// GIVEN
	m := &module{}
	cfg := &agentcfg.AgentConfiguration{
		Flux: &agentcfg.FluxCF{},
	}

	// WHEN
	err := m.DefaultAndValidateConfiguration(cfg)

	// THEN
	require.NoError(t, err)
	assert.True(t, *cfg.Flux.Enabled)
}

func TestModule_DefaultAndValidateConfiguration_WithEnabledFluxModuleSetToFalse(t *testing.T) {
	// GIVEN
	m := &module{}
	enabledFluxModule := false
	cfg := &agentcfg.AgentConfiguration{
		Flux: &agentcfg.FluxCF{
			Enabled: &enabledFluxModule,
		},
	}

	// WHEN
	err := m.DefaultAndValidateConfiguration(cfg)

	// THEN
	require.NoError(t, err)
	assert.False(t, *cfg.Flux.Enabled)
}

func TestModule_Run_NotStartedWhenNotEnabled(t *testing.T) {
	// GIVEN
	ctrl := gomock.NewController(t)
	mockReconciliationRunner := NewMockreconciliationRunner(ctrl)
	configChannel := make(chan *agentcfg.AgentConfiguration, 1)
	m := &module{
		runner: mockReconciliationRunner,
	}
	enabledFluxModule := false
	cfg := &agentcfg.AgentConfiguration{
		Flux: &agentcfg.FluxCF{
			Enabled: &enabledFluxModule,
		},
	}

	// THEN
	mockReconciliationRunner.EXPECT().run(gomock.Any(), gomock.Any()).Times(0)

	// WHEN
	err := m.DefaultAndValidateConfiguration(cfg)
	require.NoError(t, err)

	configChannel <- cfg
	close(configChannel)

	m.Run(context.Background(), configChannel)
}

func TestModule_Run_StartedWhenEnabledNotGiven(t *testing.T) {
	// GIVEN
	ctrl := gomock.NewController(t)
	mockReconciliationRunner := NewMockreconciliationRunner(ctrl)
	configChannel := make(chan *agentcfg.AgentConfiguration, 1)
	m := &module{
		runner: mockReconciliationRunner,
	}
	cfg := &agentcfg.AgentConfiguration{
		Flux: &agentcfg.FluxCF{},
	}

	// THEN
	mockReconciliationRunner.EXPECT().run(gomock.Any(), gomock.Any()).Times(1)

	// WHEN
	err := m.DefaultAndValidateConfiguration(cfg)
	require.NoError(t, err)

	configChannel <- cfg
	close(configChannel)

	m.Run(context.Background(), configChannel)
}
