package ticdc

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"testing"

	"github.com/stretchr/testify/require"
	"google.golang.org/grpc/metadata"
)

func TestWithDataflowUserUsesCanonicalIdentityAndPreservesTracing(t *testing.T) {
	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(
		dataflowUserMetadataKey, "caller-controlled",
		"traceparent", "00-trace-span-01",
	))

	ctx, err := withDataflowUser(ctx, 123, 0)
	require.NoError(t, err)
	md, ok := metadata.FromOutgoingContext(ctx)
	require.True(t, ok)
	require.Equal(t, []string{"00-trace-span-01"}, md.Get("traceparent"))
	require.Len(t, md.Get(dataflowUserMetadataKey), 1)
	require.NotEqual(t, "caller-controlled", md.Get(dataflowUserMetadataKey)[0])

	raw, err := base64.StdEncoding.DecodeString(md.Get(dataflowUserMetadataKey)[0])
	require.NoError(t, err)
	var user dataflowUser
	require.NoError(t, json.Unmarshal(raw, &user))
	require.Equal(t, uint64(123), user.TenantID)
	require.True(t, user.IsImpersonated)
	require.Equal(t, []dataflowProject{{ID: 0}}, user.Projects)
}

func TestParseProjectID(t *testing.T) {
	projectID, err := ParseProjectID("")
	require.NoError(t, err)
	require.Zero(t, projectID)

	projectID, err = ParseProjectID("456")
	require.NoError(t, err)
	require.Equal(t, uint64(456), projectID)

	for _, value := range []string{"0", "-1", "project-a"} {
		t.Run(value, func(t *testing.T) {
			_, err := ParseProjectID(value)
			require.ErrorIs(t, err, ErrUpstream)
		})
	}
}

func TestResolveArchitecture(t *testing.T) {
	for _, test := range []struct {
		deployType   string
		deployTypeV2 string
		want         Architecture
	}{
		{deployType: "dedicated", want: ArchitectureDedicated},
		{deployTypeV2: "Dedicated", want: ArchitectureDedicated},
		{deployType: "premium", want: ArchitectureNextGen},
		{deployType: "byoc-host", want: ArchitectureNextGen},
		{deployTypeV2: "byoc resource pool", want: ArchitectureNextGen},
		{deployType: "starter", want: ArchitectureNextGen},
		{deployTypeV2: "essential", want: ArchitectureEssential},
		{deployType: "future-non-dedicated-plan", want: ArchitectureNextGen},
		{deployType: "starter", deployTypeV2: "dedicated", want: ArchitectureDedicated},
	} {
		got, err := ResolveArchitecture(test.deployType, test.deployTypeV2)
		require.NoError(t, err)
		require.Equal(t, test.want, got)
	}

}
