package byoc

import (
	"context"
	"errors"
	"testing"

	awssdk "github.com/aws/aws-sdk-go-v2/aws"
)

type errorCredentialsProvider struct {
	err error
}

func (p errorCredentialsProvider) Retrieve(context.Context) (awssdk.Credentials, error) {
	return awssdk.Credentials{}, p.err
}

func TestLoadBYOCAWSConfigFallsBackToCLIExportForLegacySSO(t *testing.T) {
	originalLoad := loadBYOCAWSConfigQuiet
	originalExport := loadBYOCAWSConfigFromExportedCredentials
	t.Cleanup(func() {
		loadBYOCAWSConfigQuiet = originalLoad
		loadBYOCAWSConfigFromExportedCredentials = originalExport
	})

	loadBYOCAWSConfigQuiet = func(context.Context, string, string) (awssdk.Config, error) {
		return awssdk.Config{
			Credentials: errorCredentialsProvider{err: errors.New("SSO session has expired or is invalid: failed to refresh cached credentials")},
		}, nil
	}
	exportCalled := false
	loadBYOCAWSConfigFromExportedCredentials = func(_ context.Context, profile, region string) (awssdk.Config, error) {
		exportCalled = true
		if profile != "customer" || region != "us-west-2" {
			t.Fatalf("fallback profile/region = %q/%q", profile, region)
		}
		return awssdk.Config{Region: region, Credentials: staticCredentialsProvider{}}, nil
	}

	cfg, err := loadBYOCAWSConfig(context.Background(), "customer", "us-west-2")
	if err != nil {
		t.Fatalf("loadBYOCAWSConfig: %v", err)
	}
	if !exportCalled {
		t.Fatal("legacy SSO refresh failure did not use AWS CLI credential export")
	}
	if cfg.Region != "us-west-2" {
		t.Fatalf("region = %q", cfg.Region)
	}
}

func TestLoadBYOCAWSConfigDoesNotFallbackForOtherCredentialErrors(t *testing.T) {
	originalLoad := loadBYOCAWSConfigQuiet
	originalExport := loadBYOCAWSConfigFromExportedCredentials
	t.Cleanup(func() {
		loadBYOCAWSConfigQuiet = originalLoad
		loadBYOCAWSConfigFromExportedCredentials = originalExport
	})

	loadBYOCAWSConfigQuiet = func(context.Context, string, string) (awssdk.Config, error) {
		return awssdk.Config{Credentials: errorCredentialsProvider{err: errors.New("credential provider failed")}}, nil
	}
	exportCalled := false
	loadBYOCAWSConfigFromExportedCredentials = func(context.Context, string, string) (awssdk.Config, error) {
		exportCalled = true
		return awssdk.Config{}, nil
	}

	_, err := loadBYOCAWSConfig(context.Background(), "customer", "us-west-2")
	if err == nil {
		t.Fatal("non-SSO credential failure must fail closed")
	}
	if exportCalled {
		t.Fatal("non-SSO credential failure must not use AWS CLI credential export")
	}
}

type staticCredentialsProvider struct{}

func (staticCredentialsProvider) Retrieve(context.Context) (awssdk.Credentials, error) {
	return awssdk.Credentials{AccessKeyID: "test", SecretAccessKey: "test"}, nil
}
