package identityruntime

import (
	"context"
	"strings"
	"testing"

	"github.com/easyai/easyai-ai-gateway/apps/api/internal/identity"
)

func TestRuntimeBuilderRejectsLoopbackHTTPOutsideLocalEnvironments(t *testing.T) {
	revision := identity.Revision{
		AuthCenterURL: "https://auth.example.com", Issuer: "https://auth.example.com/issuer/easyai",
		PublicBaseURL: "https://api.example.com", WebBaseURL: "https://gateway.example.com",
		SecurityEventIssuer: "https://auth.example.com/ssf", SecurityEventConfigURL: "https://auth.example.com/.well-known/ssf-configuration/ssf",
		SessionRevocation: true,
	}
	production := &RuntimeBuilder{config: RuntimeBuilderConfig{AppEnv: "production"}}
	for _, test := range []struct {
		name   string
		mutate func(*identity.Revision)
	}{
		{name: "auth center", mutate: func(value *identity.Revision) { value.AuthCenterURL = "http://localhost:18000" }},
		{name: "OIDC issuer", mutate: func(value *identity.Revision) { value.Issuer = "http://localhost:18003/issuer/easyai" }},
		{name: "public base", mutate: func(value *identity.Revision) { value.PublicBaseURL = "http://127.0.0.1:18089" }},
		{name: "web base", mutate: func(value *identity.Revision) { value.WebBaseURL = "http://localhost:5178" }},
		{name: "SSF issuer", mutate: func(value *identity.Revision) { value.SecurityEventIssuer = "http://localhost:18004/ssf" }},
		{name: "SSF configuration", mutate: func(value *identity.Revision) {
			value.SecurityEventConfigURL = "http://localhost:18004/.well-known/ssf-configuration/ssf"
		}},
	} {
		t.Run(test.name, func(t *testing.T) {
			candidate := revision
			test.mutate(&candidate)
			if _, err := production.Build(context.Background(), candidate); err == nil || !strings.Contains(err.Error(), "HTTPS") {
				t.Fatalf("production runtime did not reject loopback HTTP %s URL: %v", test.name, err)
			}
		})
	}
	localRevision := revision
	localRevision.AuthCenterURL = "http://localhost:18000"
	localRevision.Issuer = "http://localhost:18003/issuer/easyai"
	localRevision.PublicBaseURL = "http://127.0.0.1:18089"
	localRevision.WebBaseURL = "http://localhost:5178"
	localRevision.SecurityEventIssuer = "http://localhost:18004/ssf"
	localRevision.SecurityEventConfigURL = "http://localhost:18004/.well-known/ssf-configuration/ssf"
	development := &RuntimeBuilder{config: RuntimeBuilderConfig{AppEnv: "development"}}
	if _, err := development.Build(context.Background(), localRevision); err == nil || strings.Contains(err.Error(), "HTTPS") {
		t.Fatalf("development runtime did not pass URL policy before completeness checks: %v", err)
	}
}

func TestSecurityEventManagerConfigBindsRuntimeToTargetRevision(t *testing.T) {
	builder := &RuntimeBuilder{config: RuntimeBuilderConfig{AppEnv: "test"}}
	revision := identity.Revision{
		ID:                    "revision-target",
		Issuer:                "https://auth.example/issuer",
		TenantID:              "tenant-public-id",
		MachineClientID:       "gateway-machine",
		PublicBaseURL:         "https://gateway.example",
		SecurityEventIssuer:   "https://auth.example/ssf/",
		SecurityEventAudience: "urn:easyai:ssf:receiver:target",
	}

	runtimeConfig := builder.securityEventManagerConfig(revision, true)
	if !runtimeConfig.StrictRevisionBinding ||
		runtimeConfig.ExpectedTransmitterIssuer != "https://auth.example/ssf" ||
		runtimeConfig.ExpectedAudience != revision.SecurityEventAudience ||
		runtimeConfig.ManagementClientID != revision.MachineClientID ||
		runtimeConfig.ExpectedOwnerKey != "identity-pairing-ssf-revision-target" {
		t.Fatalf("runtime SSF binding config=%#v", runtimeConfig)
	}

	recoveryConfig := builder.securityEventManagerConfig(revision, false)
	if recoveryConfig.StrictRevisionBinding {
		t.Fatal("conflict recovery was incorrectly blocked by strict Revision binding")
	}
	if recoveryConfig.ExpectedOwnerKey != runtimeConfig.ExpectedOwnerKey {
		t.Fatal("recovery manager lost the target owner needed for explicit validation")
	}
}
