package redact

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

type bad struct {
	Ban     string
	ABanC   string
	private string
	Public  string
}

func TestAsMapRedactKeys(t *testing.T) {
	banned := []string{"ban"}
	out, err := AsMapRedactKeys(banned, nil)
	assert.Nil(t, err)
	assert.Nil(t, out)
	b := bad{Ban: "secret", ABanC: "ABanC", Public: "okay", private: "private"}
	result := map[string]interface{}{"Ban": "redacted", "ABanC": "redacted", "Public": "okay"}
	out, err = AsMapRedactKeys(banned, b)
	assert.Nil(t, err)
	assert.Equal(t, result, out)
	out, err = AsMapRedactKeys(banned, &b)
	assert.Nil(t, err)
	assert.Equal(t, result, out)
}

type ClusterCreateReq struct {
	OrgId                uint64   `protobuf:"varint,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
	Name                 string   `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
	RootPassword         string   `protobuf:"bytes,3,opt,name=root_password,json=rootPassword,proto3" json:"root_password,omitempty"`
	Provider             string   `protobuf:"bytes,4,opt,name=provider,proto3" json:"provider,omitempty"`
	Region               string   `protobuf:"bytes,5,opt,name=region,proto3" json:"region,omitempty"`
	ProfileName          string   `protobuf:"bytes,6,opt,name=profile_name,json=profileName,proto3" json:"profile_name,omitempty"`
	TikvCount            uint32   `protobuf:"varint,7,opt,name=tikv_count,json=tikvCount,proto3" json:"tikv_count,omitempty"`
	TidbCount            uint32   `protobuf:"varint,8,opt,name=tidb_count,json=tidbCount,proto3" json:"tidb_count,omitempty"`
	TiflashCount         uint32   `protobuf:"varint,9,opt,name=tiflash_count,json=tiflashCount,proto3" json:"tiflash_count,omitempty"`
	ProjectId            uint64   `protobuf:"varint,10,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"`
	AwsAccessKeyId       string   `protobuf:"bytes,11,opt,name=aws_access_key_id,json=awsAccessKeyId,proto3" json:"aws_access_key_id,omitempty"`
	AwsSecretAccessKey   string   `protobuf:"bytes,12,opt,name=aws_secret_access_key,json=awsSecretAccessKey,proto3" json:"aws_secret_access_key,omitempty"`
	LightningConfig      string   `protobuf:"bytes,13,opt,name=lightning_config,json=lightningConfig,proto3" json:"lightning_config,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func TestAsMapRedactKeys2(t *testing.T) {
	out, err := AsMapRedactKeys(PasswordFields, ClusterCreateReq{})
	assert.Nil(t, err)
	assert.Equal(t, map[string]interface{}{}, out)

	req := ClusterCreateReq{
		OrgId:                1,
		Name:                 "name",
		RootPassword:         "secret",
		Provider:             "provider",
		Region:               "region",
		ProfileName:          "north",
		TikvCount:            1,
		TidbCount:            1,
		TiflashCount:         1,
		ProjectId:            1,
		AwsAccessKeyId:       "aws_access_key_id",
		AwsSecretAccessKey:   "aws_secret_access_key",
		LightningConfig:      "lightning_config",
		XXX_NoUnkeyedLiteral: struct{}{},
		XXX_unrecognized:     []byte("hmm"),
		XXX_sizecache:        1,
	}
	result := map[string]interface{}{
		"name":                  "name",
		"org_id":                float64(1),
		"profile_name":          "north",
		"project_id":            float64(1),
		"provider":              "provider",
		"region":                "region",
		"root_password":         "redacted",
		"aws_access_key_id":     "redacted",
		"aws_secret_access_key": "redacted",
		"lightning_config":      "redacted",
		"tidb_count":            float64(1),
		"tiflash_count":         float64(1),
		"tikv_count":            float64(1),
	}
	out, err = AsMapRedactKeys(PasswordFields, req)
	assert.Nil(t, err)
	assert.Equal(t, result, out)

	out, err = AsMapRedactKeys(PasswordFields, &req)
	assert.Nil(t, err)
	assert.Equal(t, result, out)
}

func TestAsMapRedactKeys_OSSAccessKeySecret(t *testing.T) {
	req := map[string]interface{}{
		"source": map[string]interface{}{
			"oss": map[string]interface{}{
				"bucket": "my-bucket",
				"accessKey": map[string]interface{}{
					"id":     "AKIAEXAMPLE",
					"secret": "super-secret",
				},
			},
		},
	}
	out, err := AsMapRedactKeys(PasswordFields, req)
	assert.Nil(t, err)
	oss := out["source"].(map[string]interface{})["oss"].(map[string]interface{})
	assert.Nil(t, oss["accessKey"])
	assert.Equal(t, "my-bucket", oss["bucket"])

	req2 := map[string]interface{}{
		"credentials": map[string]interface{}{
			"id":     "AKIAEXAMPLE",
			"secret": "super-secret",
		},
	}
	out2, err := AsMapRedactKeys(PasswordFields, req2)
	assert.Nil(t, err)
	creds := out2["credentials"].(map[string]interface{})
	assert.Equal(t, "AKIAEXAMPLE", creds["id"])
	assert.Equal(t, "redacted", creds["secret"])
}
