package storage

import (
	"context"
	"testing"

	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/service-proxy/pkg/checker/core"
)

func TestS3Checker_GetBucketRegion(t *testing.T) {
	ctx := context.Background()

	t.Run("explicit region takes precedence", func(t *testing.T) {
		c := NewS3Checker(&core.S3Params{Region: "ap-southeast-1"})
		region, err := c.getBucketRegion(ctx, "bucket")
		require.NoError(t, err)
		assert.Equal(t, "ap-southeast-1", region)
	})

	t.Run("custom endpoint falls back to default region without AWS lookup", func(t *testing.T) {
		c := NewS3Checker(&core.S3Params{
			Endpoint: "https://s3.oss-us-east-1.aliyuncs.com",
		})
		region, err := c.getBucketRegion(ctx, "bucket")
		require.NoError(t, err)
		assert.Equal(t, defaultRegionHint, region)
	})
}

func TestS3Checker_S3ClientOptions(t *testing.T) {
	t.Run("alibaba oss endpoint uses virtual-hosted style", func(t *testing.T) {
		const endpoint = "https://oss-ap-southeast-1.aliyuncs.com"
		c := NewS3Checker(&core.S3Params{Endpoint: endpoint})
		optFns := c.s3ClientOptions()
		require.Len(t, optFns, 1)

		opts := &s3.Options{}
		for _, fn := range optFns {
			fn(opts)
		}
		require.NotNil(t, opts.BaseEndpoint)
		assert.Equal(t, endpoint, *opts.BaseEndpoint)
		// OSS forbids path-style access, so the client must use virtual-hosted
		// style.
		assert.False(t, opts.UsePathStyle)
	})

	t.Run("other custom endpoint keeps path style", func(t *testing.T) {
		const endpoint = "http://minio.local:9000"
		c := NewS3Checker(&core.S3Params{Endpoint: endpoint})
		optFns := c.s3ClientOptions()
		require.Len(t, optFns, 1)

		opts := &s3.Options{}
		for _, fn := range optFns {
			fn(opts)
		}
		require.NotNil(t, opts.BaseEndpoint)
		assert.Equal(t, endpoint, *opts.BaseEndpoint)
		assert.True(t, opts.UsePathStyle)
	})

	t.Run("no endpoint returns no options", func(t *testing.T) {
		c := NewS3Checker(&core.S3Params{})
		assert.Empty(t, c.s3ClientOptions())
	})
}

func TestIsAlibabaOSSEndpoint(t *testing.T) {
	cases := []struct {
		endpoint string
		want     bool
	}{
		{"https://oss-ap-southeast-1.aliyuncs.com", true},
		{"https://s3.oss-us-east-1.aliyuncs.com", true},
		{"http://oss-cn-hangzhou.aliyuncs.com", true},
		{"https://s3.amazonaws.com", false},
		{"https://s3.us-west-2.amazonaws.com", false},
		{"http://minio.local:9000", false},
		{"", false},
	}
	for _, tc := range cases {
		assert.Equalf(t, tc.want, isAlibabaOSSEndpoint(tc.endpoint), "endpoint=%s", tc.endpoint)
	}
}
