package config

import (
	"testing"

	. "github.com/onsi/gomega"
)

func TestIsTestStage(t *testing.T) {
	g := NewGomegaWithT(t)
	g.Expect(IsTestStage()).To(BeFalse())
	globalConf.ServerConfig.Stage = StageLocal
	g.Expect(IsTestStage()).To(BeTrue())
	globalConf.ServerConfig.Stage = StageDev
	g.Expect(IsTestStage()).To(BeTrue())
	globalConf.ServerConfig.Stage = StageStaging
	g.Expect(IsTestStage()).To(BeFalse())
	globalConf.ServerConfig.Stage = StageProd
	g.Expect(IsTestStage()).To(BeFalse())
}

func TestWorkerMode(t *testing.T) {
	g := NewGomegaWithT(t)
	g.Expect(IsWorkerMode()).To(BeFalse())
	SetWorkMode(WorkModeWorker)
	g.Expect(IsWorkerMode()).To(BeTrue())
}

// TestResolveNewArchBaseImage pins down the three-layer lookup:
//
//  1. cdc.newArch.regionConfig[].baseImage wins when set for that
//     (provider, region) pair.
//  2. cdc.newArch.baseImagePerProvider[provider] is the per-provider
//     default; lookup falls back to lowercase if the exact key misses
//     (yaml configs can be cased inconsistently across services).
//  3. cdc.newArch.baseImage is the global fallback.
//
// Each case is structured so the *only* layer that should answer is
// the one being asserted; the others are set to clearly-wrong values
// to catch precedence regressions.
func TestResolveNewArchBaseImage(t *testing.T) {
	g := NewGomegaWithT(t)

	defer func(saved *CentralConfig) { globalConf = saved }(globalConf)

	cases := []struct {
		name     string
		cfg      *CentralConfig
		provider string
		region   string
		want     string
	}{
		{
			name: "region override wins",
			cfg: &CentralConfig{
				CDCConfig: CDCConfig{NewArch: CDCNewArchConfig{
					BaseImage:            "legacy-image",
					BaseImagePerProvider: map[string]string{"alicloud": "provider-image"},
					RegionConfig: []CDCNewArchRegionalConfig{{
						Provider: "alicloud", Region: "ap-southeast-1",
						BaseImage: "region-image",
					}},
				}},
			},
			provider: "alicloud", region: "ap-southeast-1",
			want: "region-image",
		},
		{
			name: "region override falls through when empty",
			cfg: &CentralConfig{
				CDCConfig: CDCConfig{NewArch: CDCNewArchConfig{
					BaseImage:            "legacy-image",
					BaseImagePerProvider: map[string]string{"alicloud": "provider-image"},
					RegionConfig: []CDCNewArchRegionalConfig{{
						Provider: "alicloud", Region: "ap-southeast-1",
					}},
				}},
			},
			provider: "alicloud", region: "ap-southeast-1",
			want: "provider-image",
		},
		{
			name: "provider catalog matches case-insensitively",
			cfg: &CentralConfig{
				CDCConfig: CDCConfig{NewArch: CDCNewArchConfig{
					BaseImage:            "legacy-image",
					BaseImagePerProvider: map[string]string{"aws": "aws-image"},
				}},
			},
			provider: "AWS", region: "us-east-1",
			want: "aws-image",
		},
		{
			name: "legacy baseImage when no override + no provider entry",
			cfg: &CentralConfig{
				CDCConfig: CDCConfig{NewArch: CDCNewArchConfig{
					BaseImage: "legacy-image",
				}},
			},
			provider: "gcp", region: "us-central1",
			want: "legacy-image",
		},
		{
			name: "empty when nothing configured",
			cfg: &CentralConfig{
				CDCConfig: CDCConfig{NewArch: CDCNewArchConfig{}},
			},
			provider: "azure", region: "eastus",
			want: "",
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			globalConf = tc.cfg
			g.Expect(ResolveNewArchBaseImage(tc.provider, tc.region)).To(Equal(tc.want))
		})
	}
}

func TestResolveNewArchVersion(t *testing.T) {
	g := NewGomegaWithT(t)

	defer func(saved *CentralConfig) { globalConf = saved }(globalConf)

	cases := []struct {
		name     string
		cfg      *CentralConfig
		provider string
		region   string
		want     string
	}{
		{
			name: "region version wins",
			cfg: &CentralConfig{
				CDCConfig: CDCConfig{NewArch: CDCNewArchConfig{
					Version: "global-version",
					RegionConfig: []CDCNewArchRegionalConfig{{
						Provider: "alicloud",
						Region:   "ap-southeast-1",
						Version:  "region-version",
					}},
				}},
			},
			provider: "alicloud", region: "ap-southeast-1",
			want: "region-version",
		},
		{
			name: "region falls through when version empty",
			cfg: &CentralConfig{
				CDCConfig: CDCConfig{NewArch: CDCNewArchConfig{
					Version: "global-version",
					RegionConfig: []CDCNewArchRegionalConfig{{
						Provider: "alicloud",
						Region:   "ap-southeast-1",
					}},
				}},
			},
			provider: "alicloud", region: "ap-southeast-1",
			want: "global-version",
		},
		{
			name: "provider matches case-insensitively",
			cfg: &CentralConfig{
				CDCConfig: CDCConfig{NewArch: CDCNewArchConfig{
					Version: "global-version",
					RegionConfig: []CDCNewArchRegionalConfig{{
						Provider: "alicloud",
						Region:   "ap-southeast-1",
						Version:  "region-version",
					}},
				}},
			},
			provider: "AliCloud", region: "ap-southeast-1",
			want: "region-version",
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			globalConf = tc.cfg
			g.Expect(ResolveNewArchVersion(tc.provider, tc.region)).To(Equal(tc.want))
		})
	}
}
