package schema

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestCloneDocumentDeepCopy(t *testing.T) {
	started := time.Now()
	bytes := int64(1024)
	lastErr := "boom"
	doc := &Document{
		ManifestRef: "m.json",
		Shards: []Shard{{
			ShardID:   "x:1",
			Phase:     PhaseImported,
			Bytes:     &bytes,
			StartedAt: &started,
			LastError: &lastErr,
			Verification: &Verification{
				OriginCounts:    map[string]int64{"k8s": 5},
				CandidateCounts: map[string]int64{"k8s": 6},
				Diffs:           nil,
			},
		}},
	}

	clone := CloneDocument(doc)

	// Mutate every nested field of the clone; the original must not move.
	*clone.Shards[0].Bytes = 2048
	*clone.Shards[0].StartedAt = started.Add(time.Hour)
	*clone.Shards[0].LastError = "changed"
	clone.Shards[0].Verification.OriginCounts["k8s"] = 99
	clone.Shards[0].Verification.CandidateCounts = nil

	assert.Equal(t, int64(1024), *doc.Shards[0].Bytes)
	assert.Equal(t, started, *doc.Shards[0].StartedAt)
	assert.Equal(t, "boom", *doc.Shards[0].LastError)
	assert.Equal(t, map[string]int64{"k8s": 5}, doc.Shards[0].Verification.OriginCounts)
	assert.Equal(t, map[string]int64{"k8s": 6}, doc.Shards[0].Verification.CandidateCounts)
}

func TestCloneDocumentPreservesNil(t *testing.T) {
	doc := &Document{Shards: []Shard{{ShardID: "x:1"}}}
	clone := CloneDocument(doc)

	assert.Nil(t, clone.Shards[0].Bytes)
	assert.Nil(t, clone.Shards[0].StartedAt)
	assert.Nil(t, clone.Shards[0].FinishedAt)
	assert.Nil(t, clone.Shards[0].VerifiedAt)
	assert.Nil(t, clone.Shards[0].LastError)
	assert.Nil(t, clone.Shards[0].Verification)

	verified := &Shard{ShardID: "x:2", Verification: &Verification{}}
	clone2 := CloneDocument(&Document{Shards: []Shard{*verified}})
	assert.NotNil(t, clone2.Shards[0].Verification)
	assert.Nil(t, clone2.Shards[0].Verification.OriginCounts, "nil maps must stay nil, not empty")
	assert.Nil(t, CloneDocument(nil))
}
