package steme

import (
	"testing"
)

// TestAssertionBuilder tests the fluent assertion builder API.
func TestAssertionBuilder(t *testing.T) {
	lifecycle := LifecycleApproved
	sourceClass := SourceClassClinical

	assertion := NewAssertion("Tesla_Inc", "has_revenue").
		WithNumber(96.7).
		WithConfidence(0.95).
		WithLifecycle(lifecycle).
		WithSourceClass(sourceClass).
		WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
		Build()

	if assertion.Subject != "Tesla_Inc" {
		t.Errorf("Subject = %s, want Tesla_Inc", assertion.Subject)
	}

	if assertion.Predicate != "has_revenue" {
		t.Errorf("Predicate = %s, want has_revenue", assertion.Predicate)
	}

	if assertion.Object.Type != "Number" {
		t.Errorf("Object.Type = %s, want Number", assertion.Object.Type)
	}

	if assertion.Object.Value != 96.7 {
		t.Errorf("Object.Value = %v, want 96.7", assertion.Object.Value)
	}

	if assertion.Confidence != 0.95 {
		t.Errorf("Confidence = %f, want 0.95", assertion.Confidence)
	}

	if assertion.Lifecycle == nil || *assertion.Lifecycle != LifecycleApproved {
		t.Errorf("Lifecycle = %v, want Approved", assertion.Lifecycle)
	}

	if assertion.SourceClass == nil || *assertion.SourceClass != SourceClassClinical {
		t.Errorf("SourceClass = %v, want Clinical", assertion.SourceClass)
	}
}

// TestAssertionValidation tests assertion validation.
func TestAssertionValidation(t *testing.T) {
	tests := []struct {
		name    string
		build   func() Assertion
		wantErr bool
	}{
		{
			name: "valid assertion",
			build: func() Assertion {
				return NewAssertion("Tesla_Inc", "has_revenue").
					WithNumber(96.7).
					WithConfidence(0.95).
					WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
					Build()
			},
			wantErr: false,
		},
		{
			name: "confidence too high",
			build: func() Assertion {
				return NewAssertion("Tesla_Inc", "has_revenue").
					WithNumber(96.7).
					WithConfidence(1.5).
					WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
					Build()
			},
			wantErr: true,
		},
		{
			name: "confidence negative",
			build: func() Assertion {
				return NewAssertion("Tesla_Inc", "has_revenue").
					WithNumber(96.7).
					WithConfidence(-0.1).
					WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
					Build()
			},
			wantErr: true,
		},
		{
			name: "missing source_hash",
			build: func() Assertion {
				return NewAssertion("Tesla_Inc", "has_revenue").
					WithNumber(96.7).
					Build()
			},
			wantErr: true,
		},
		{
			name: "invalid source_hash length",
			build: func() Assertion {
				return NewAssertion("Tesla_Inc", "has_revenue").
					WithNumber(96.7).
					WithSourceHash("00").
					Build()
			},
			wantErr: true,
		},
		{
			name: "invalid source_hash hex",
			build: func() Assertion {
				return NewAssertion("Tesla_Inc", "has_revenue").
					WithNumber(96.7).
					WithSourceHash("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz").
					Build()
			},
			wantErr: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			assertion := tt.build()
			err := assertion.Validate()

			if (err != nil) != tt.wantErr {
				t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}
