package wsl

import (
	"os"
	"path/filepath"
	"testing"

	"golang.org/x/tools/go/analysis/analysistest"
)

func TestDefaultConfig(t *testing.T) {
	t.Parallel()

	dirs, err := os.ReadDir("./testdata/src/default_config")
	if err != nil {
		t.Fatal(err)
	}

	for _, tc := range dirs {
		t.Run(tc.Name(), func(t *testing.T) {
			t.Parallel()

			testdata := analysistest.TestData()
			analyzer := NewAnalyzer(NewConfig())

			analysistest.RunWithSuggestedFixes(t, testdata, analyzer, filepath.Join("default_config", tc.Name()))
		})
	}
}

func TestDefaultConfigFromAnalyzer(t *testing.T) {
	t.Parallel()

	testdata := analysistest.TestData()
	analyzer := NewAnalyzer(nil)

	analysistest.RunWithSuggestedFixes(t, testdata, analyzer, filepath.Join("default_config", "if"))
}

func TestWithConfig(t *testing.T) {
	t.Parallel()

	testdata := analysistest.TestData()

	for _, tc := range []struct {
		subdir   string
		configFn func(*Configuration)
	}{
		{
			subdir: "no_check_decl",
			configFn: func(config *Configuration) {
				config.Checks.Remove(CheckDecl)
			},
		},
		{
			subdir: "whole_block",
			configFn: func(config *Configuration) {
				config.AllowWholeBlock = true
			},
		},
		{
			subdir: "first_in_block_n1",
			configFn: func(config *Configuration) {
				config.AllowFirstInBlock = true
			},
		},
		{
			subdir: "case_max_lines",
			configFn: func(config *Configuration) {
				config.CaseMaxLines = 3
			},
		},
		{
			subdir: "branch_max_lines",
			configFn: func(config *Configuration) {
				config.BranchMaxLines = 5
			},
		},
		{
			subdir: "exclusive_short_decl",
			configFn: func(config *Configuration) {
				config.Checks.Add(CheckAssignExclusive)
			},
		},
		{
			subdir: "assign_expr",
			configFn: func(config *Configuration) {
				config.Checks.Add(CheckAssignExpr)
			},
		},
		{
			subdir: "disable_all",
			configFn: func(config *Configuration) {
				config.Checks = NoChecks()
			},
		},
		{
			subdir: "err_only",
			configFn: func(config *Configuration) {
				config.Checks = NoChecks()
				config.Checks.Add(CheckErr)
			},
		},
		{
			subdir: "append_only",
			configFn: func(config *Configuration) {
				config.Checks = NoChecks()
				config.Checks.Add(CheckAppend)
			},
		},
		{
			subdir: "all_enabled",
			configFn: func(config *Configuration) {
				config.Checks = AllChecks()
				config.CaseMaxLines = 1
			},
		},
		{
			subdir: "after_block",
			configFn: func(config *Configuration) {
				config.Checks = NoChecks()
				config.Checks.Add(CheckCaseTrailingNewline)
				config.Checks.Add(CheckAfterBlock)

				config.CaseMaxLines = 1
			},
		},
		{
			subdir: "after_stmts",
			configFn: func(config *Configuration) {
				config.Checks = NoChecks()
				config.Checks.Add(CheckAfterDecl)
				config.Checks.Add(CheckAfterDefer)
				config.Checks.Add(CheckAfterExpr)
				config.Checks.Add(CheckAfterGo)
			},
		},
		{
			subdir: "after_decl_with_grouping",
			configFn: func(config *Configuration) {
				config.Checks = NoChecks()
				config.Checks.Add(CheckDecl)
				config.Checks.Add(CheckAfterDecl)
			},
		},
		{
			subdir: "cuddle_max_statements_2",
			configFn: func(config *Configuration) {
				config.CuddleMaxStatements = 2
			},
		},
		{
			subdir: "cuddle_max_statements_unlimited",
			configFn: func(config *Configuration) {
				config.CuddleMaxStatements = 9999
			},
		},
		{
			subdir: "cuddle_max_statements_whole_block",
			configFn: func(config *Configuration) {
				config.CuddleMaxStatements = 9999
				config.AllowWholeBlock = true
			},
		},
		{
			subdir: "cuddle_max_statements_zero",
			configFn: func(config *Configuration) {
				config.CuddleMaxStatements = 0
			},
		},
		{
			subdir: "cuddle_group",
			configFn: func(config *Configuration) {
				config.Checks.Add(CheckCuddleGroup)
			},
		},
		{
			subdir: "cuddle_group_max_2",
			configFn: func(config *Configuration) {
				config.Checks.Add(CheckCuddleGroup)
				config.CuddleMaxStatements = 2
			},
		},
	} {
		t.Run(tc.subdir, func(t *testing.T) {
			t.Parallel()

			config := NewConfig()
			tc.configFn(config)

			analyzer := NewAnalyzer(config)
			analysistest.RunWithSuggestedFixes(t, testdata, analyzer, filepath.Join("with_config", tc.subdir))
		})
	}
}
