package tenant

import (
	"context"
	"errors"
	"testing"
)

type credentialDefaultsTestProvisioner struct {
	provider   string
	defaults   CredentialProvisionRequest
	defaultsOK bool
	shared     CredentialProvisionRequest
	sharedOK   bool
}

func (p *credentialDefaultsTestProvisioner) Provision(context.Context, string) (*ClusterInfo, error) {
	return nil, errors.New("not implemented")
}

func (*credentialDefaultsTestProvisioner) InitSchema(context.Context, string) error { return nil }

func (p *credentialDefaultsTestProvisioner) ProviderType() string { return p.provider }

func (p *credentialDefaultsTestProvisioner) DefaultCredentials() (CredentialProvisionRequest, bool) {
	return p.defaults, p.defaultsOK
}

func (p *credentialDefaultsTestProvisioner) DefaultSharedCredentials() (CredentialProvisionRequest, bool) {
	return p.shared, p.sharedOK
}

func TestDefaultCredentialsForProviderUsesOneFallbackRule(t *testing.T) {
	regular := CredentialProvisionRequest{PublicKey: "regular-public", PrivateKey: "regular-private"}
	shared := CredentialProvisionRequest{PublicKey: "shared-public", PrivateKey: "shared-private"}
	tests := []struct {
		name      string
		provider  string
		defaults  CredentialProvisionRequest
		defaultOK bool
		shared    CredentialProvisionRequest
		sharedOK  bool
		want      CredentialProvisionRequest
		wantOK    bool
	}{
		{name: "shared provider prefers shared defaults", provider: ProviderTiDBCloudNativeShared, defaults: regular, defaultOK: true, shared: shared, sharedOK: true, want: shared, wantOK: true},
		{name: "shared provider uses shared defaults", provider: ProviderTiDBCloudNativeShared, shared: shared, sharedOK: true, want: shared, wantOK: true},
		{name: "shared provider falls back to regular defaults", provider: ProviderTiDBCloudNativeShared, defaults: regular, defaultOK: true, want: regular, wantOK: true},
		{name: "non-shared provider does not use shared defaults", provider: ProviderTiDBCloudNative, shared: shared, sharedOK: true},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			provisioner := &credentialDefaultsTestProvisioner{
				provider: tt.provider, defaults: tt.defaults, defaultsOK: tt.defaultOK,
				shared: tt.shared, sharedOK: tt.sharedOK,
			}
			got, ok := DefaultCredentialsForProvider(provisioner, tt.provider)
			if ok != tt.wantOK || got != tt.want {
				t.Fatalf("credentials = %#v/%t, want %#v/%t", got, ok, tt.want, tt.wantOK)
			}
		})
	}
}
