package alicloud

import (
	"encoding/json"
	"testing"

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

func TestBuildKeyPolicy(t *testing.T) {
	tests := []struct {
		name      string
		accountID string
		userRoles []string
		wantStmts int
	}{
		{
			name:      "no user roles",
			accountID: "119285303511",
			userRoles: nil,
			wantStmts: 1,
		},
		{
			name:      "with user roles",
			accountID: "119285303511",
			userRoles: []string{"acs:ram::5753857577068077:role/node-role-1"},
			wantStmts: 2,
		},
		{
			name:      "with multiple user roles from different accounts",
			accountID: "119285303511",
			userRoles: []string{
				"acs:ram::5753857577068077:role/node-role-1",
				"acs:ram::5028760335873601:role/node-role-2",
			},
			wantStmts: 2,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			policy, err := buildKeyPolicy(tt.accountID, tt.userRoles)
			require.NoError(t, err)

			var doc Policy
			err = json.Unmarshal([]byte(policy), &doc)
			require.NoError(t, err)

			assert.Equal(t, "1", doc.Version)
			assert.Len(t, doc.Statement, tt.wantStmts)

			// First statement: account root with full KMS permissions
			assert.Equal(t, "Allow", doc.Statement[0].Effect)
			assert.Equal(t, []string{"kms:*"}, doc.Statement[0].Action)
			assert.Contains(t, doc.Statement[0].Principal["RAM"], "acs:ram::"+tt.accountID+":*")

			// Second statement: user roles (if present)
			if len(tt.userRoles) > 0 {
				assert.Equal(t, "Allow", doc.Statement[1].Effect)
				for _, role := range tt.userRoles {
					assert.Contains(t, doc.Statement[1].Principal["RAM"], role)
				}
				assert.Contains(t, doc.Statement[1].Action, "kms:Encrypt")
				assert.Contains(t, doc.Statement[1].Action, "kms:Decrypt")
				assert.Contains(t, doc.Statement[1].Action, "kms:GenerateDataKey")
				assert.Contains(t, doc.Statement[1].Action, "kms:DescribeKey")
			}
		})
	}
}
