// Copyright Earl Warren <contact@earl-warren.org>
// Copyright Loïc Dachary <loic@dachary.org>
// SPDX-License-Identifier: MIT

package generic

import (
	"context"
	"testing"

	"code.forgejo.org/f3/gof3/v3/id"
	"code.forgejo.org/f3/gof3/v3/kind"
	"code.forgejo.org/f3/gof3/v3/tree/generic"
	"code.forgejo.org/f3/gof3/v3/tree/memory"

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

func TestCompare(t *testing.T) {
	ctx := context.Background()

	aTree := NewMemoryTree(ctx, "O")
	testTreeBuild(t, aTree, 2)
	bTree := NewMemoryTree(ctx, "O")
	testTreeBuild(t, bTree, 2)

	assert.True(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))

	{
		toDelete := generic.NewPathFromString("/O-A/O-B")

		aTree.Find(toDelete).Delete(ctx)
		assert.False(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))

		bTree.Find(toDelete).Delete(ctx)
		assert.True(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))
	}

	{
		content := "OTHER CONTENT"
		toModify := generic.NewPathFromString("/O-A/O-F")
		aNode := aTree.Find(toModify)
		memory.SetContent(aNode, content)
		aNode.Upsert(ctx)
		assert.False(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))

		bNode := bTree.Find(toModify)
		memory.SetContent(bNode, content)
		bNode.Upsert(ctx)

		assert.True(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))
	}

	{
		toModify := generic.NewPathFromString("/O-A/O-F")
		aTree.Find(toModify).SetKind(kind.Kind("???"))
		assert.False(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))
		bTree.Find(toModify).SetKind(kind.Kind("???"))
		assert.True(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))
	}

	{
		pathToMap := generic.NewPathFromString("/O-A/O-J/O-M")
		mappedID := id.NewNodeID("MAPPED")
		aTree.Find(pathToMap).SetMappedID(mappedID)
		assert.False(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))

		bNode := bTree.Find(pathToMap).Delete(ctx)
		bNode.SetID(mappedID)
		parentPathToMap := generic.NewPathFromString("/O-A/O-J")
		bTree.Find(parentPathToMap).SetChild(bNode)
		assert.True(t, generic.TreeCompare(ctx, aTree, generic.NewPathFromString(""), bTree, generic.NewPathFromString("")))
	}
}
