package procedure

import (
	"context"
	"errors"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/s3/s3iface"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"
	"k8s.io/utils/pointer"
)

// EmptyBucket deletes all objects in the bucket
func EmptyBucket(ctx context.Context, client s3iface.S3API, bucket string) error {
	if bucket == "" {
		return errors.New("bucket name is empty")
	}

	// check files exist
	listReq := s3.ListObjectsInput{
		Bucket:  aws.String(bucket),
		MaxKeys: pointer.Int64(1),
	}
	out, err := client.ListObjectsWithContext(ctx, &listReq)
	if err != nil {
		if isNotFoundError(err) {
			return nil
		}
		return err
	}
	if len(out.Contents) == 0 {
		return nil
	}

	// delete all
	iter := s3manager.NewDeleteListIterator(client, &s3.ListObjectsInput{
		Bucket: aws.String(bucket),
	})
	if err := s3manager.NewBatchDeleteWithClient(client).Delete(ctx, iter); err != nil {
		return err
	}
	return nil
}

func isNotFoundError(err error) bool {
	if err == nil {
		return false
	}
	if strings.Contains(err.Error(), "failed to get region") {
		// regard as not found error
		return true
	}
	if err1, ok := (err).(awserr.Error); ok {
		switch err1.Code() {
		case s3.ErrCodeNoSuchBucket, s3.ErrCodeNoSuchKey, s3.ErrCodeNoSuchUpload:
			return true
		}
	}
	return false
}
