package describe

import (
	"testing"

	"github.com/stretchr/testify/assert"

	cfg "github.com/cloudposse/atmos/pkg/config"
	describe "github.com/cloudposse/atmos/pkg/describe"
	"github.com/cloudposse/atmos/pkg/schema"
	u "github.com/cloudposse/atmos/pkg/utils"
)

func TestDescribeStacks(t *testing.T) {
	configAndStacksInfo := schema.ConfigAndStacksInfo{}

	cliConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
	assert.Nil(t, err)

	stacks, err := describe.ExecuteDescribeStacks(cliConfig, "", nil, nil, nil, false, false)
	assert.Nil(t, err)

	dependentsYaml, err := u.ConvertToYAML(stacks)
	assert.Nil(t, err)
	t.Log(dependentsYaml)
}

func TestDescribeStacksWithFilter1(t *testing.T) {
	configAndStacksInfo := schema.ConfigAndStacksInfo{}

	cliConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
	assert.Nil(t, err)

	stack := "tenant1-ue2-dev"

	stacks, err := describe.ExecuteDescribeStacks(cliConfig, stack, nil, nil, nil, false, false)
	assert.Nil(t, err)

	dependentsYaml, err := u.ConvertToYAML(stacks)
	assert.Nil(t, err)
	t.Log(dependentsYaml)
}

func TestDescribeStacksWithFilter2(t *testing.T) {
	configAndStacksInfo := schema.ConfigAndStacksInfo{}

	cliConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
	assert.Nil(t, err)

	stack := "tenant1-ue2-dev"
	components := []string{"infra/vpc"}

	stacks, err := describe.ExecuteDescribeStacks(cliConfig, stack, components, nil, nil, false, false)
	assert.Nil(t, err)

	dependentsYaml, err := u.ConvertToYAML(stacks)
	assert.Nil(t, err)
	t.Log(dependentsYaml)
}

func TestDescribeStacksWithFilter3(t *testing.T) {
	configAndStacksInfo := schema.ConfigAndStacksInfo{}

	cliConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
	assert.Nil(t, err)

	stack := "tenant1-ue2-dev"
	sections := []string{"vars"}

	stacks, err := describe.ExecuteDescribeStacks(cliConfig, stack, nil, nil, sections, false, false)
	assert.Nil(t, err)

	dependentsYaml, err := u.ConvertToYAML(stacks)
	assert.Nil(t, err)
	t.Log(dependentsYaml)
}

func TestDescribeStacksWithFilter4(t *testing.T) {
	configAndStacksInfo := schema.ConfigAndStacksInfo{}

	cliConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
	assert.Nil(t, err)

	componentTypes := []string{"terraform"}
	sections := []string{"none"}

	stacks, err := describe.ExecuteDescribeStacks(cliConfig, "", nil, componentTypes, sections, false, false)
	assert.Nil(t, err)

	dependentsYaml, err := u.ConvertToYAML(stacks)
	assert.Nil(t, err)
	t.Log(dependentsYaml)
}

func TestDescribeStacksWithFilter5(t *testing.T) {
	configAndStacksInfo := schema.ConfigAndStacksInfo{}

	cliConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
	assert.Nil(t, err)

	componentTypes := []string{"terraform"}
	components := []string{"top-level-component1"}
	sections := []string{"vars"}

	stacks, err := describe.ExecuteDescribeStacks(cliConfig, "", components, componentTypes, sections, false, false)
	assert.Nil(t, err)
	assert.Equal(t, 8, len(stacks))

	tenant1Ue2DevStack := stacks["tenant1-ue2-dev"].(map[string]any)
	tenant1Ue2DevStackComponents := tenant1Ue2DevStack["components"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraform := tenant1Ue2DevStackComponents["terraform"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraformComponent := tenant1Ue2DevStackComponentsTerraform["top-level-component1"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraformComponentVars := tenant1Ue2DevStackComponentsTerraformComponent["vars"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraformComponentVarsTenant := tenant1Ue2DevStackComponentsTerraformComponentVars["tenant"].(string)
	tenant1Ue2DevStackComponentsTerraformComponentVarsStage := tenant1Ue2DevStackComponentsTerraformComponentVars["stage"].(string)
	tenant1Ue2DevStackComponentsTerraformComponentVarsEnvironment := tenant1Ue2DevStackComponentsTerraformComponentVars["environment"].(string)
	assert.Equal(t, "tenant1", tenant1Ue2DevStackComponentsTerraformComponentVarsTenant)
	assert.Equal(t, "ue2", tenant1Ue2DevStackComponentsTerraformComponentVarsEnvironment)
	assert.Equal(t, "dev", tenant1Ue2DevStackComponentsTerraformComponentVarsStage)

	stacksYaml, err := u.ConvertToYAML(stacks)
	assert.Nil(t, err)
	t.Log(stacksYaml)
}

func TestDescribeStacksWithFilter6(t *testing.T) {
	configAndStacksInfo := schema.ConfigAndStacksInfo{}

	cliConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
	assert.Nil(t, err)

	stack := "tenant1-ue2-dev"
	componentTypes := []string{"terraform"}
	components := []string{"top-level-component1"}
	sections := []string{"workspace"}

	stacks, err := describe.ExecuteDescribeStacks(cliConfig, "tenant1-ue2-dev", components, componentTypes, sections, false, false)
	assert.Nil(t, err)
	assert.Equal(t, 1, len(stacks))

	tenant1Ue2DevStack := stacks[stack].(map[string]any)
	tenant1Ue2DevStackComponents := tenant1Ue2DevStack["components"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraform := tenant1Ue2DevStackComponents["terraform"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraformComponent := tenant1Ue2DevStackComponentsTerraform["top-level-component1"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraformWorkspace := tenant1Ue2DevStackComponentsTerraformComponent["workspace"].(string)
	assert.Equal(t, "tenant1-ue2-dev", tenant1Ue2DevStackComponentsTerraformWorkspace)

	stacksYaml, err := u.ConvertToYAML(stacks)
	assert.Nil(t, err)
	t.Log(stacksYaml)
}

func TestDescribeStacksWithFilter7(t *testing.T) {
	configAndStacksInfo := schema.ConfigAndStacksInfo{}

	cliConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
	assert.Nil(t, err)

	stack := "tenant1-ue2-dev"
	componentTypes := []string{"terraform"}
	components := []string{"test/test-component-override-3"}
	sections := []string{"workspace"}

	stacks, err := describe.ExecuteDescribeStacks(cliConfig, stack, components, componentTypes, sections, false, false)
	assert.Nil(t, err)
	assert.Equal(t, 1, len(stacks))

	tenant1Ue2DevStack := stacks[stack].(map[string]any)
	tenant1Ue2DevStackComponents := tenant1Ue2DevStack["components"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraform := tenant1Ue2DevStackComponents["terraform"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraformComponent := tenant1Ue2DevStackComponentsTerraform["test/test-component-override-3"].(map[string]any)
	tenant1Ue2DevStackComponentsTerraformWorkspace := tenant1Ue2DevStackComponentsTerraformComponent["workspace"].(string)
	assert.Equal(t, "test-component-override-3-workspace", tenant1Ue2DevStackComponentsTerraformWorkspace)

	stacksYaml, err := u.ConvertToYAML(stacks)
	assert.Nil(t, err)
	t.Log(stacksYaml)
}
