package cmd
import (
 "fmt"
 "net/http"
 "net/http/httptest"
 "strings"
 "sync/atomic"
 "testing"
 "github.com/minio/minio-go/v7"
 "github.com/minio/minio/internal/bucket/replication"
 xhttp "github.com/minio/minio/internal/http"
)
func TestReviewR6LegacyPurgeRetries(t *testing.T) {
	var deletes atomic.Int32
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodHead {
			w.Header().Set(xhttp.AmzDeleteMarker, "true")
			w.WriteHeader(http.StatusMethodNotAllowed)
			return
		}
		deletes.Add(1)
		w.WriteHeader(http.StatusNoContent)
	}))
	defer server.Close()
	client, err := minio.New(strings.TrimPrefix(server.URL, "http://"), &minio.Options{Region: "us-east-1", MaxRetries: 1})
	if err != nil {
		t.Fatal(err)
	}
	old := globalBucketTargetSys
	globalBucketTargetSys = &BucketTargetSys{hc: map[string]epHealth{client.EndpointURL().Host: {Online: true}}}
	defer func() { globalBucketTargetSys = old }()
	d := DeletedObjectReplicationInfo{Bucket: "source", DeletedObject: DeletedObject{ObjectName: "marker", DeleteMarker: true, DeleteMarkerVersionID: mustGetUUID()}}
	d.ReplicationState.Targets = map[string]replication.StatusType{"arn1": replication.Completed}
	d.ReplicationState.PurgeTargets = map[string]VersionPurgeStatusType{"arn1": replication.VersionPurgePending}
	result := replicateDeleteToTarget(t.Context(), d, &TargetClient{Client: client, ARN: "arn1", Bucket: "target"})
	t.Logf("remote DELETE calls=%d, creation=%s, purge=%s", deletes.Load(), result.ReplicationStatus, result.VersionPurgeStatus)
	if deletes.Load() != 1 || result.VersionPurgeStatus != replication.VersionPurgeComplete {
		t.Error("pending legacy purge was not delivered")
	}
}


func TestReviewR6PurgeExits(t *testing.T) {
 for _, tc := range []struct{name string; creation replication.StatusType; purge VersionPurgeStatusType; head int; existing bool; want VersionPurgeStatusType; wantCalls int; wantReset bool}{
 {"head_forbidden", replication.Pending, replication.VersionPurgePending, 403, false, replication.VersionPurgeFailed, 1, false},
 {"failed_resync", replication.Completed, replication.VersionPurgePending, 405, true, replication.VersionPurgeFailed, 2, false},
 {"already_purged", replication.Pending, replication.VersionPurgeComplete, 405, false, replication.VersionPurgeComplete, 0, false},
 } {
 t.Run(tc.name, func(t *testing.T){
 var calls atomic.Int32
 server:=httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter,r *http.Request){
 calls.Add(1)
 if r.Method==http.MethodHead {w.Header().Set(xhttp.AmzDeleteMarker,"true"); w.WriteHeader(tc.head);return}
 w.WriteHeader(403);fmt.Fprint(w,`<Error><Code>AccessDenied</Code></Error>`)
 }))
 defer server.Close()
 client,err:=minio.New(strings.TrimPrefix(server.URL,"http://"),&minio.Options{Region:"us-east-1",MaxRetries:1});if err!=nil{t.Fatal(err)}
 old:=globalBucketTargetSys;globalBucketTargetSys=&BucketTargetSys{hc:map[string]epHealth{client.EndpointURL().Host:{Online:true}}};defer func(){globalBucketTargetSys=old}()
 d:=DeletedObjectReplicationInfo{Bucket:"source",DeletedObject:DeletedObject{ObjectName:"marker",DeleteMarker:true,DeleteMarkerVersionID:mustGetUUID()}}
 d.ReplicationState.Targets=map[string]replication.StatusType{"arn1":tc.creation}
 d.ReplicationState.PurgeTargets=map[string]VersionPurgeStatusType{"arn1":tc.purge}
 if tc.existing {d.OpType=replication.ExistingObjectReplicationType}
 got:=replicateDeleteToTarget(t.Context(),d,&TargetClient{Client:client,ARN:"arn1",Bucket:"target",ResetID:"new-reset"})
 t.Logf("calls=%d, creation=%s, purge=%s, reset=%q",calls.Load(),got.ReplicationStatus,got.VersionPurgeStatus,got.ResyncTimestamp)
 if got.ReplicationStatus!=tc.creation || got.VersionPurgeStatus!=tc.want || int(calls.Load())!=tc.wantCalls || (got.ResyncTimestamp!="")!=tc.wantReset {t.Errorf("operation classified inconsistently: %+v",got)}
 })
 }
}
