package watch_graph //nolint:staticcheck

import (
	"fmt"
	"testing"

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

func TestArcAttrs(t *testing.T) {
	var a ArcAttrs
	assert.True(t, a.IsZero())
}

func TestArcTypeSet(t *testing.T) {
	assert.Zero(t, UnknownArcType) // must be zero so that setting it does not change anything

	arcTypes := []ArcType{OwnerReferenceArcType, ReferenceArcType, TransitiveReferenceArcType}

	for _, arcType := range arcTypes {
		t.Run(fmt.Sprintf("%s+%s", arcType, UnknownArcType), func(t *testing.T) {
			var a ArcTypeSet
			a.Add(arcType)
			a.Add(UnknownArcType)
			assert.True(t, a.Contains(arcType))
		})
		t.Run(arcType.String(), func(t *testing.T) {
			var a ArcTypeSet
			assert.False(t, a.Contains(arcType))

			a.Add(arcType)
			assert.True(t, a.Contains(arcType))

			a.Add(arcType)
			assert.True(t, a.Contains(arcType))

			a.Remove(arcType)
			assert.False(t, a.Contains(arcType))
		})
	}

	for t1, arcType1 := range arcTypes {
		for t2, arcType2 := range arcTypes {
			// Do not compare values, compare positions.
			// If there is a bug in the test or different constants have the same value, this test will fail.
			if t1 == t2 {
				continue
			}
			t.Run(fmt.Sprintf("%s+%s", arcType1, arcType2), func(t *testing.T) {
				var a ArcTypeSet
				assert.False(t, a.Contains(arcType1))
				assert.False(t, a.Contains(arcType2))

				a.Add(arcType1)
				assert.True(t, a.Contains(arcType1))

				a.Add(arcType2)
				assert.True(t, a.Contains(arcType1))
				assert.True(t, a.Contains(arcType2))

				a.Remove(arcType1)
				assert.False(t, a.Contains(arcType1))
				assert.True(t, a.Contains(arcType2))

				a.Remove(arcType2)
				assert.False(t, a.Contains(arcType1))
				assert.False(t, a.Contains(arcType2))
			})
		}
	}
}

func TestParseArcTypeStr(t *testing.T) {
	arcTypes := []ArcType{UnknownArcType, OwnerReferenceArcType, ReferenceArcType, TransitiveReferenceArcType}

	for _, arcType := range arcTypes {
		t.Run(fmt.Sprintf("%s roundtrip", arcType), func(t *testing.T) {
			actual := ParseArcTypeStr(arcType.String())
			assert.Equal(t, arcType, actual)
		})
	}
}
