package common

import (
	"fmt"
	"testing"

	"github.com/stretchr/testify/require"
	. "github.com/tidbcloud/dataflow-service-e2e/internal/model"
	br_model "github.com/tidbcloud/dataflow-service-e2e/internal/tidbcloud/dedicated/consoleapi/br/model"
)

type statusCodeError struct {
	code int
}

func (e statusCodeError) Error() string {
	return fmt.Sprintf("HTTP %d", e.code)
}

func (e statusCodeError) Code() int {
	return e.code
}

func TestIsUnauthorizedAPIError(t *testing.T) {
	tests := map[string]struct {
		err  error
		want bool
	}{
		"direct 401 API error": {
			err:  statusCodeError{code: 401},
			want: true,
		},
		"wrapped 401 API error": {
			err:  fmt.Errorf("list restores: %w", statusCodeError{code: 401}),
			want: true,
		},
		"non-401 API error": {
			err:  statusCodeError{code: 403},
			want: false,
		},
		"ordinary error": {
			err:  fmt.Errorf("connection reset"),
			want: false,
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			require.Equal(t, tc.want, isUnauthorizedAPIError(tc.err))
		})
	}
}

func TestPickSecondaryRegionFromBackupOptions(t *testing.T) {
	tests := map[string]struct {
		requiresClusterCreation bool
		configuredRegions       []string
		optionRegionNames       []string
		expectedResult          string
		expectedErrMessage      string
	}{
		"does not create a cluster and selects the first API option": {
			optionRegionNames: []string{"us-west-1", "us-east-1"},
			expectedResult:    "us-west-1",
		},
		"creates a cluster and selects the first API option in the configured-region intersection": {
			requiresClusterCreation: true,
			configuredRegions:       []string{"us-west-2", "us-east-1"},
			optionRegionNames:       []string{"us-west-1", "us-east-1"},
			expectedResult:          "us-east-1",
		},
		"creates a cluster and rejects an empty configured-region intersection": {
			requiresClusterCreation: true,
			configuredRegions:       []string{"us-west-2", "eu-central-1"},
			optionRegionNames:       []string{"us-west-1", "us-east-1"},
			expectedErrMessage:      "no API-advertised secondary region is configured for cluster creation",
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			regionOptions := make([]*br_model.BackupOptionsRespRegionOptions, 0, len(tc.optionRegionNames))
			for _, regionName := range tc.optionRegionNames {
				regionOptions = append(regionOptions, &br_model.BackupOptionsRespRegionOptions{
					Region: &br_model.DataflowRegionInfo{Name: regionName},
				})
			}

			got, err := pickSecondaryRegionFromBackupOptions(
				&TiDBDedicatedEntity{
					ClusterID:               "123",
					TiDBDedicatedDimensions: TiDBDedicatedDimensions{Region: "us-west-2"},
				},
				&br_model.BackupOptionsRespDualRegionOptions{RegionOptions: regionOptions},
				tc.requiresClusterCreation,
				tc.configuredRegions,
			)
			if tc.expectedErrMessage != "" {
				require.ErrorContains(t, err, tc.expectedErrMessage)
				return
			}

			require.NoError(t, err)
			require.Equal(t, tc.expectedResult, got)
		})
	}
}
