package service

import (
	"fmt"
	"testing"

	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/engine"
	"github.com/stretchr/testify/require"
	"go.uber.org/zap/zapcore"
)

func TestBigQueryFailureLogFieldsContainOnlySafeDiagnostics(t *testing.T) {
	err := fmt.Errorf("query execution failed: %w", &engine.BigQueryQueryError{
		QueryID:       "job-1",
		ErrorSource:   "googleapi",
		Reason:        "invalidQuery",
		ErrorCount:    2,
		MessageShape:  "unrecognized_name",
		HasSuggestion: true,
	})

	fields := bigQueryFailureLogFields(err)
	require.Len(t, fields, 6)
	encoded := make(map[string]interface{}, len(fields))
	for _, field := range fields {
		value := field.Interface
		switch field.Type {
		case zapcore.StringType:
			value = field.String
		case zapcore.Int64Type:
			value = field.Integer
		case zapcore.BoolType:
			value = field.Integer == 1
		}
		encoded[field.Key] = value
	}
	require.Equal(t, "job-1", encoded["bigquery_query_id"])
	require.Equal(t, "googleapi", encoded["bigquery_error_source"])
	require.Equal(t, "invalidQuery", encoded["bigquery_reason"])
	require.Equal(t, int64(2), encoded["bigquery_error_count"])
	require.Equal(t, "unrecognized_name", encoded["bigquery_message_shape"])
	require.Equal(t, true, encoded["bigquery_has_suggestion"])
	require.NotContains(t, fmt.Sprint(encoded), "customer_secret")
	require.NotContains(t, fmt.Sprint(encoded), "private_field")
}

func TestBigQueryTopSQLSetupFailureLogFieldsContainOnlyBoundedDiagnostics(t *testing.T) {
	err := fmt.Errorf("setup failed: %w", &engine.BigQueryTopSQLSetupError{
		Operation:      "create_or_replace_external_table",
		ObjectKind:     "topsql_tidb",
		ObjectState:    "legacy_broad_parquet",
		Reason:         "invalidQuery",
		ErrorSource:    "bigquery",
		HTTPStatus:     400,
		QueryID:        "job-1",
		InstanceCount:  2,
		SourceURICount: 2,
	})

	fields := bigQueryTopSQLSetupFailureLogFields(err)
	require.Len(t, fields, 9)
	encoded := make(map[string]interface{}, len(fields))
	for _, field := range fields {
		value := field.Interface
		switch field.Type {
		case zapcore.StringType:
			value = field.String
		case zapcore.Int64Type:
			value = field.Integer
		}
		encoded[field.Key] = value
	}
	require.Equal(t, "create_or_replace_external_table", encoded["topsql_setup_operation"])
	require.Equal(t, int64(2), encoded["topsql_instance_count"])
	require.Equal(t, int64(2), encoded["topsql_source_uri_count"])
	require.NotContains(t, fmt.Sprint(encoded), "gs://")
	require.NotContains(t, fmt.Sprint(encoded), "SELECT")
}
