package runtimeassembly

import (
	"context"
	"errors"
	"github.com/nexuscrm/shared/pkg/models"
	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/applicationnavigationv1"
	common "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/commonv1"
	"testing"
)

func TestNavigationVisibilityUsesTargetIdentityAndNeverLabel(t *testing.T) {
	grants := map[string]bool{"resource": true, "start": true}
	for _, item := range []semantic.Item{
		{ID: "collection", Label: "Renamed", Target: semantic.Target{Resource: &semantic.ResourceTarget{ResourceType: "Resource"}}},
		{ID: "page", Label: "Renamed", Target: semantic.Target{Page: &semantic.PageTarget{ID: "Start"}}},
	} {
		if !navigationItemVisible(item, grants) {
			t.Fatal("rename hid allowed target")
		}
		if navigationItemVisible(item, map[string]bool{"renamed": true}) {
			t.Fatal("display label became permission authority")
		}
		if navigationItemVisible(item, nil) {
			t.Fatal("missing grant became visible")
		}
	}
}

type navigationSchemaProbe struct {
	calls   []string
	schemas map[string]*models.ObjectMetadata
	err     error
}

func (p *navigationSchemaProbe) GetSchemaByAPIName(_ context.Context, name string) (*models.ObjectMetadata, error) {
	p.calls = append(p.calls, name)
	return p.schemas[name], p.err
}
func TestNavigationResourceValidationPreservesUnavailableExistingTargets(t *testing.T) {
	item := semantic.Item{ID: "existing", Label: "Renamed", Target: semantic.Target{Resource: &semantic.ResourceTarget{ResourceType: "Removed"}}}
	probe := &navigationSchemaProbe{}
	runtime := &ApplicationNavigationRuntime{schemas: probe}
	if err := runtime.validateResourceTargets(context.Background(), semantic.Document{Items: []semantic.Item{item}}, []semantic.Item{item}); err != nil || len(probe.calls) != 0 {
		t.Fatalf("retained reference was revalidated: %v %v", err, probe.calls)
	}
	item.Target.Resource = &semantic.ResourceTarget{ResourceType: "New"}
	err := runtime.validateResourceTargets(context.Background(), semantic.Document{}, []semantic.Item{item})
	var failure *common.Failure
	if !errors.As(err, &failure) || failure.Category != common.FailureInvalidRequest {
		t.Fatalf("unknown new reference accepted: %v", err)
	}
	probe.schemas = map[string]*models.ObjectMetadata{"New": {APIName: "New"}}
	if err := runtime.validateResourceTargets(context.Background(), semantic.Document{}, []semantic.Item{item}); err != nil {
		t.Fatal(err)
	}
	probe.err = errors.New("metadata unavailable")
	if err := runtime.validateResourceTargets(context.Background(), semantic.Document{}, []semantic.Item{item}); !errors.Is(err, probe.err) {
		t.Fatalf("metadata read failed open: %v", err)
	}
}
