//go:build integration

package aws

import (
	"context"
	"testing"
	"time"

	awssdk "github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi"
	tagtypes "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi/types"
)

type purgeScopeTaggingFixture struct {
	resources []tagtypes.ResourceTagMapping
}

func (f *purgeScopeTaggingFixture) GetResources(
	context.Context,
	*resourcegroupstaggingapi.GetResourcesInput,
	...func(*resourcegroupstaggingapi.Options),
) (*resourcegroupstaggingapi.GetResourcesOutput, error) {
	return &resourcegroupstaggingapi.GetResourcesOutput{ResourceTagMappingList: f.resources}, nil
}

func TestIntegration_BroadPurgeRequiresAllScopeTTLEvidenceToExpire(t *testing.T) {
	now := time.Date(2026, 8, 4, 10, 0, 0, 0, time.UTC)
	tests := []struct {
		name       string
		taggedTTL  time.Time
		iamTTL     time.Time
		wantCount  int
		wantMaxTTL time.Time
	}{
		{
			name:      "regional expired but IAM successor is live",
			taggedTTL: now.Add(-time.Hour),
			iamTTL:    now.Add(time.Hour),
		},
		{
			name:      "IAM residue expired but regional successor is live",
			taggedTTL: now.Add(time.Hour),
			iamTTL:    now.Add(-time.Hour),
		},
		{
			name:       "all evidence expired",
			taggedTTL:  now.Add(-2 * time.Hour),
			iamTTL:     now.Add(-time.Hour),
			wantCount:  1,
			wantMaxTTL: now.Add(-time.Hour),
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			tags := func(ttl time.Time) map[string]string {
				return map[string]string{
					TagManaged: "true",
					TagOwner:   "owner@example.com",
					TagSession: "reused-session",
					TagTTL:     ttl.Format(time.RFC3339),
				}
			}
			regional, err := FindManagedScopes(context.Background(), &purgeScopeTaggingFixture{
				resources: []tagtypes.ResourceTagMapping{{Tags: mapToTaggingTags(tags(tt.taggedTTL))}},
			})
			if err != nil {
				t.Fatal(err)
			}
			inventory := &IAMInventory{roles: []iamInventoryEntry{{tags: tags(tt.iamTTL)}}}
			merged := MergeManagedScopes(regional, inventory.ManagedScopes())
			expired := FilterExpiredManagedScopes(merged, now)
			if len(expired) != tt.wantCount {
				t.Fatalf("expired scopes = %#v, want count %d", expired, tt.wantCount)
			}
			if tt.wantCount == 1 && !expired[0].TTL.Equal(tt.wantMaxTTL) {
				t.Fatalf("merged TTL = %s, want latest evidence %s", expired[0].TTL, tt.wantMaxTTL)
			}
		})
	}
}

func mapToTaggingTags(tags map[string]string) []tagtypes.Tag {
	out := make([]tagtypes.Tag, 0, len(tags))
	for key, value := range tags {
		out = append(out, tagtypes.Tag{Key: awssdk.String(key), Value: awssdk.String(value)})
	}
	return out
}
