package lifecyclecompare

import (
	"testing"

	"cloud.google.com/go/storage"
	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aws/aws-sdk-go-v2/aws"
	s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
	"github.com/stretchr/testify/assert"
)

func TestAWSLifecycleRulesEqual(t *testing.T) {
	ruleA := s3types.LifecycleRule{
		ID:     aws.String("rule-a"),
		Status: s3types.ExpirationStatusEnabled,
		Filter: &s3types.LifecycleRuleFilter{Prefix: aws.String("prefix-a/")},
		Expiration: &s3types.LifecycleExpiration{
			Days: aws.Int32(30),
		},
	}
	ruleB := s3types.LifecycleRule{
		ID:     aws.String("rule-b"),
		Status: s3types.ExpirationStatusEnabled,
		Filter: &s3types.LifecycleRuleFilter{Prefix: aws.String("prefix-b/")},
		Transitions: []s3types.Transition{
			{
				Days:         aws.Int32(32),
				StorageClass: s3types.TransitionStorageClassGlacierIr,
			},
		},
	}

	assert.True(t, AWSLifecycleRulesEqual([]s3types.LifecycleRule{ruleA, ruleB}, []s3types.LifecycleRule{ruleB, ruleA}))

	changed := s3types.LifecycleRule{
		ID:     aws.String("rule-a"),
		Status: s3types.ExpirationStatusEnabled,
		Filter: &s3types.LifecycleRuleFilter{Prefix: aws.String("prefix-a/")},
		Expiration: &s3types.LifecycleExpiration{
			Days: aws.Int32(31),
		},
	}
	assert.False(t, AWSLifecycleRulesEqual([]s3types.LifecycleRule{ruleA}, []s3types.LifecycleRule{changed}))
}

func TestOSSLifecycleRulesEqual(t *testing.T) {
	status := "Enabled"
	ruleA := oss.LifecycleRule{
		ID:     oss.Ptr("rule-a"),
		Prefix: oss.Ptr("prefix-a/"),
		Status: &status,
		Expiration: &oss.LifecycleRuleExpiration{
			Days: oss.Ptr(int32(30)),
		},
	}
	ruleChanged := oss.LifecycleRule{
		ID:     oss.Ptr("rule-a"),
		Prefix: oss.Ptr("prefix-a/"),
		Status: &status,
		Expiration: &oss.LifecycleRuleExpiration{
			Days: oss.Ptr(int32(31)),
		},
	}

	assert.True(t, OSSLifecycleRulesEqual([]oss.LifecycleRule{ruleA}, []oss.LifecycleRule{ruleA}))
	assert.False(t, OSSLifecycleRulesEqual([]oss.LifecycleRule{ruleA}, []oss.LifecycleRule{ruleChanged}))
}

func TestGCSLifecycleRulesEqual(t *testing.T) {
	ruleA := storage.LifecycleRule{
		Action: storage.LifecycleAction{Type: storage.DeleteAction},
		Condition: storage.LifecycleCondition{
			AgeInDays:     30,
			MatchesPrefix: []string{"prefix-a/"},
		},
	}
	ruleB := storage.LifecycleRule{
		Action: storage.LifecycleAction{
			Type:         storage.SetStorageClassAction,
			StorageClass: "COLDLINE",
		},
		Condition: storage.LifecycleCondition{
			AgeInDays:     32,
			MatchesPrefix: []string{"prefix-a/"},
		},
	}

	assert.True(t, GCSLifecycleRulesEqual([]storage.LifecycleRule{ruleA, ruleB}, []storage.LifecycleRule{ruleB, ruleA}))

	changed := ruleA
	changed.Condition.AgeInDays = 31
	assert.False(t, GCSLifecycleRulesEqual([]storage.LifecycleRule{ruleA}, []storage.LifecycleRule{changed}))
}

func TestAzureLifecycleRulesEqual(t *testing.T) {
	enabled := true
	deleteDays30 := float32(30)
	deleteDays31 := float32(31)
	ruleA := &armstorage.ManagementPolicyRule{
		Name:    aws.String("rule-a_delete"),
		Enabled: &enabled,
		Definition: &armstorage.ManagementPolicyDefinition{
			Filters: &armstorage.ManagementPolicyFilter{
				PrefixMatch: []*string{aws.String("bucket/prefix-a/")},
			},
			Actions: &armstorage.ManagementPolicyAction{
				BaseBlob: &armstorage.ManagementPolicyBaseBlob{
					Delete: &armstorage.DateAfterModification{
						DaysAfterModificationGreaterThan: &deleteDays30,
					},
				},
			},
		},
	}
	ruleB := &armstorage.ManagementPolicyRule{
		Name:    aws.String("rule-a_delete"),
		Enabled: &enabled,
		Definition: &armstorage.ManagementPolicyDefinition{
			Filters: &armstorage.ManagementPolicyFilter{
				PrefixMatch: []*string{aws.String("bucket/prefix-a/")},
			},
			Actions: &armstorage.ManagementPolicyAction{
				BaseBlob: &armstorage.ManagementPolicyBaseBlob{
					Delete: &armstorage.DateAfterModification{
						DaysAfterModificationGreaterThan: &deleteDays31,
					},
				},
			},
		},
	}

	assert.True(t, AzureLifecycleRulesEqual([]*armstorage.ManagementPolicyRule{ruleA}, []*armstorage.ManagementPolicyRule{ruleA}))
	assert.False(t, AzureLifecycleRulesEqual([]*armstorage.ManagementPolicyRule{ruleA}, []*armstorage.ManagementPolicyRule{ruleB}))
}
