@ontology @uko
Feature: UKO Ontology Domain Registry and Turtle Validation
  As an ACMS developer
  I need a central registry for UKO domain ontologies
  So that analyzers, strategies, and the graph backend can discover
  namespace IRIs, class inventories, and DetailLevelMaps for each domain

  Background:
    Given the UKO ontology registry module is available

  # ---------------------------------------------------------------------------
  # Domain Lookup
  # ---------------------------------------------------------------------------

  @ontology @registry
  Scenario: Look up Layer 0 domain by prefix
    When I look up domain "uko:"
    Then the domain IRI should be "https://cleveragents.ai/ontology/uko#"
    And the domain layer should be 0
    And the domain classes should contain "uko:InformationUnit"
    And the domain classes should contain "uko:Container"
    And the domain classes should contain "uko:Atom"
    And the domain classes should contain "uko:Annotation"
    And the domain classes should contain "uko:Boundary"

  @ontology @registry
  Scenario: Look up uko-code: domain by prefix
    When I look up domain "uko-code:"
    Then the domain IRI should be "https://cleveragents.ai/ontology/uko/code#"
    And the domain layer should be 1
    And the domain classes should contain "uko-code:Module"
    And the domain classes should contain "uko-code:Callable"
    And the domain classes should contain "uko-code:TypeDefinition"
    And the domain classes should contain "uko-code:TestCase"
    And the domain classes should contain "uko-code:Import"

  @ontology @registry
  Scenario: Look up uko-doc: domain by prefix
    When I look up domain "uko-doc:"
    Then the domain IRI should be "https://cleveragents.ai/ontology/uko/doc#"
    And the domain layer should be 1
    And the domain should have 17 classes
    And the domain classes should contain "uko-doc:Document"
    And the domain classes should contain "uko-doc:Section"
    And the domain classes should contain "uko-doc:Paragraph"
    And the domain classes should contain "uko-doc:Citation"
    And the domain classes should contain "uko-doc:TableOfContents"

  @ontology @registry
  Scenario: Look up uko-data: domain by prefix
    When I look up domain "uko-data:"
    Then the domain IRI should be "https://cleveragents.ai/ontology/uko/data#"
    And the domain layer should be 1
    And the domain should have 13 classes
    And the domain classes should contain "uko-data:Table"
    And the domain classes should contain "uko-data:Column"
    And the domain classes should contain "uko-data:ForeignKey"
    And the domain classes should contain "uko-data:StoredProcedure"
    And the domain classes should contain "uko-data:View"

  @ontology @registry
  Scenario: Look up uko-infra: domain by prefix
    When I look up domain "uko-infra:"
    Then the domain IRI should be "https://cleveragents.ai/ontology/uko/infra#"
    And the domain layer should be 1
    And the domain should have 7 classes
    And the domain classes should contain "uko-infra:Service"
    And the domain classes should contain "uko-infra:Endpoint"
    And the domain classes should contain "uko-infra:Port"
    And the domain classes should contain "uko-infra:ConfigBlock"
    And the domain classes should contain "uko-infra:ConfigKey"

  @ontology @registry @negative
  Scenario: Look up unknown domain raises ValueError
    When I look up domain "uko-xyz:"
    Then a ValueError should have been raised with message "Unknown UKO domain prefix"

  @ontology @registry @negative
  Scenario: Look up empty domain prefix raises ValueError
    When I look up an empty domain prefix
    Then a ValueError should have been raised with message "must not be empty"

  # ---------------------------------------------------------------------------
  # List Domains
  # ---------------------------------------------------------------------------

  @ontology @registry
  Scenario: list_domains returns all 5 registered domains
    When I list all domains
    Then the domain list should have 5 entries
    And the domain list should be sorted by layer then prefix

  @ontology @registry
  Scenario: get_layer1_domains returns exactly 4 domains
    When I get Layer 1 domains
    Then the Layer 1 list should have 4 entries
    And every domain in the Layer 1 list should have layer 1

  # ---------------------------------------------------------------------------
  # DetailLevelMap — spec-complete resolution for uko-code:
  # ---------------------------------------------------------------------------

  @ontology @detail_levels
  Scenario: uko-code: map resolves all 10 named levels
    When I look up domain "uko-code:"
    Then the detail map should resolve "MODULE_LISTING" to 0
    And the detail map should resolve "MODULE_GRAPH" to 1
    And the detail map should resolve "MEMBER_LISTING" to 2
    And the detail map should resolve "MEMBER_SUMMARY" to 3
    And the detail map should resolve "SIGNATURES" to 4
    And the detail map should resolve "SIGNATURES_WITH_DOCS" to 5
    And the detail map should resolve "STRUCTURAL_OUTLINE" to 6
    And the detail map should resolve "KEY_LOGIC" to 7
    And the detail map should resolve "NEAR_COMPLETE" to 8
    And the detail map should resolve "FULL_SOURCE" to 9

  # ---------------------------------------------------------------------------
  # DetailLevelMap — spec-complete resolution for uko-doc:
  # ---------------------------------------------------------------------------

  @ontology @detail_levels
  Scenario: uko-doc: map resolves all 11 named levels
    When I look up domain "uko-doc:"
    Then the detail map should resolve "TITLE_ONLY" to 0
    And the detail map should resolve "TABLE_OF_CONTENTS_L1" to 1
    And the detail map should resolve "TABLE_OF_CONTENTS_L2" to 2
    And the detail map should resolve "FULL_TOC" to 3
    And the detail map should resolve "TOC_WITH_SUMMARIES" to 4
    And the detail map should resolve "SECTION_OVERVIEWS" to 5
    And the detail map should resolve "TOPIC_SENTENCES" to 6
    And the detail map should resolve "PARAGRAPH_SUMMARIES" to 7
    And the detail map should resolve "STRUCTURAL_DETAIL" to 8
    And the detail map should resolve "NEAR_COMPLETE" to 9
    And the detail map should resolve "FULL_CONTENT" to 10

  # ---------------------------------------------------------------------------
  # DetailLevelMap — spec-complete resolution for uko-data:
  # ---------------------------------------------------------------------------

  @ontology @detail_levels
  Scenario: uko-data: map resolves all 12 named levels
    When I look up domain "uko-data:"
    Then the detail map should resolve "SCHEMA_LISTING" to 0
    And the detail map should resolve "TABLE_LISTING" to 1
    And the detail map should resolve "COLUMN_LISTING" to 2
    And the detail map should resolve "TYPED_COLUMNS" to 3
    And the detail map should resolve "CONSTRAINTS" to 4
    And the detail map should resolve "RELATIONSHIPS" to 5
    And the detail map should resolve "INDEXES_AND_STATS" to 6
    And the detail map should resolve "DDL" to 7
    And the detail map should resolve "DDL_WITH_TRIGGERS" to 8
    And the detail map should resolve "FULL_PROCEDURES" to 9
    And the detail map should resolve "WITH_SAMPLE_DATA" to 10
    And the detail map should resolve "FULL_CATALOG" to 11

  # ---------------------------------------------------------------------------
  # DetailLevelMap — spec-complete resolution for uko-infra:
  # ---------------------------------------------------------------------------

  @ontology @detail_levels
  Scenario: uko-infra: map resolves all 9 named levels
    When I look up domain "uko-infra:"
    Then the detail map should resolve "SERVICE_LISTING" to 0
    And the detail map should resolve "SERVICE_GRAPH" to 1
    And the detail map should resolve "ENDPOINT_LISTING" to 2
    And the detail map should resolve "ENDPOINT_DETAIL" to 3
    And the detail map should resolve "CONFIG_KEYS" to 4
    And the detail map should resolve "CONFIG_VALUES" to 5
    And the detail map should resolve "RESOURCE_LIMITS" to 6
    And the detail map should resolve "FULL_CONFIG" to 7
    And the detail map should resolve "WITH_DEPLOYMENT" to 8

  # ---------------------------------------------------------------------------
  # DetailLevelMap — integer depth resolution
  # ---------------------------------------------------------------------------

  @ontology @detail_levels
  Scenario: Integer depth is clamped to max_depth
    When I look up domain "uko-code:"
    Then the detail map should clamp depth 15 to 9
    And the detail map should clamp depth 0 to 0
    And the detail map should clamp depth 5 to 5

  @ontology @detail_levels @negative
  Scenario: Unknown named level raises ValueError
    When I look up domain "uko-code:"
    And I try to resolve level "NONEXISTENT_LEVEL"
    Then a ValueError should have been raised with message "Unknown detail level"

  # ---------------------------------------------------------------------------
  # DetailLevelMap — inheritance chain (Layer 3 → 2 → 1 → 0)
  # ---------------------------------------------------------------------------

  @ontology @detail_levels @inheritance
  Scenario: build_detail_map_chain wires parent linkage
    When I build a detail map chain from "uko-code:"
    Then the chain should resolve "MODULE_LISTING" to 0
    And the chain should resolve "FULL_SOURCE" to 9
    And the chain max depth should be 9

  @ontology @detail_levels @inheritance
  Scenario: Two-level chain inherits parent levels
    Given a custom DetailLevelMap for domain "uko-oo:" with parent "uko-code:" and levels:
      | level             | depth |
      | CLASS_HIERARCHY   | 3     |
    When I resolve "MODULE_LISTING" on the custom map
    Then the resolved depth should be 0
    When I resolve "CLASS_HIERARCHY" on the custom map
    Then the resolved depth should be 3

  @ontology @detail_levels @inheritance @negative
  Scenario: build_detail_map_chain with no prefixes raises ValueError
    When I build a detail map chain with no prefixes
    Then a ValueError should have been raised with message "At least one domain prefix"

  # ---------------------------------------------------------------------------
  # Turtle Validation — well-formed file
  # ---------------------------------------------------------------------------

  @ontology @turtle
  Scenario: The project uko.ttl file passes Turtle validation
    When I validate the project Turtle file "docs/ontology/uko.ttl"
    Then the validation should produce 0 errors

  @ontology @turtle
  Scenario: Valid minimal Turtle content passes validation
    When I validate Turtle content:
      """
      @prefix ex: <http://example.org/> .
      ex:Thing a ex:Class .
      """
    Then the validation should produce 0 errors

  # ---------------------------------------------------------------------------
  # Turtle Validation — error detection
  # ---------------------------------------------------------------------------

  @ontology @turtle @negative
  Scenario: Undeclared prefix is caught
    When I validate Turtle content:
      """
      @prefix ex: <http://example.org/> .
      bogus:Thing a ex:Class .
      """
    Then the validation should produce at least 1 error
    And the first error should contain "undeclared prefix"

  @ontology @turtle @negative
  Scenario: Unbalanced angle brackets are caught
    When I validate Turtle content:
      """
      @prefix ex: <http://example.org/> .
      ex:Thing a <http://example.org/Class .
      """
    Then the validation should produce at least 1 error
    And the first error should contain "unbalanced angle brackets"

  @ontology @turtle @negative
  Scenario: Empty content is caught
    When I validate empty Turtle content
    Then the validation should produce at least 1 error
    And the first error should contain "Empty"

  @ontology @turtle @negative
  Scenario: validate_turtle_file with missing file raises FileNotFoundError
    When I validate Turtle file "/nonexistent/path/to/file.ttl"
    Then a FileNotFoundError should have been raised

  @ontology @turtle @negative
  Scenario: validate_turtle_file with empty path raises ValueError
    When I validate Turtle file with empty path
    Then a ValueError should have been raised with message "must not be empty"

  # ---------------------------------------------------------------------------
  # Turtle Content — Layer 1 prefix declarations
  # ---------------------------------------------------------------------------

  @ontology @turtle
  Scenario: The project uko.ttl declares all Layer 1 prefixes
    When I read the project Turtle file "docs/ontology/uko.ttl"
    Then the content should contain prefix "uko-code:"
    And the content should contain prefix "uko-doc:"
    And the content should contain prefix "uko-data:"
    And the content should contain prefix "uko-infra:"

  @ontology @turtle
  Scenario: The project uko.ttl declares uko-doc: classes
    When I read the project Turtle file "docs/ontology/uko.ttl"
    Then the content should contain "uko-doc:Document"
    And the content should contain "uko-doc:Section"
    And the content should contain "uko-doc:Paragraph"
    And the content should contain "uko-doc:Citation"

  @ontology @turtle
  Scenario: The project uko.ttl declares uko-data: classes
    When I read the project Turtle file "docs/ontology/uko.ttl"
    Then the content should contain "uko-data:Table"
    And the content should contain "uko-data:Column"
    And the content should contain "uko-data:ForeignKey"
    And the content should contain "uko-data:View"

  @ontology @turtle
  Scenario: The project uko.ttl declares uko-infra: classes
    When I read the project Turtle file "docs/ontology/uko.ttl"
    Then the content should contain "uko-infra:Service"
    And the content should contain "uko-infra:Endpoint"
    And the content should contain "uko-infra:Port"
    And the content should contain "uko-infra:ConfigBlock"

  # ---------------------------------------------------------------------------
  # Universal View Guarantee
  # ---------------------------------------------------------------------------

  @ontology @universal_view
  Scenario: Every Layer 1 class ultimately inherits from uko:InformationUnit
    When I read the project Turtle file "docs/ontology/uko.ttl"
    Then every Layer 1 class should have a subClassOf chain to uko:InformationUnit

  @ontology @universal_view
  Scenario: All Layer 1 domain DetailLevelMaps include depth 0
    When I get Layer 1 domains
    Then every domain detail map should resolve integer depth 0 to 0
