Feature: Resource type inheritance and polymorphic matching
  ADR-042 defines single-inheritance for resource types.
  Types may declare an `inherits` field pointing to one parent type.
  The inheritance engine resolves chains, merges fields, detects cycles,
  enforces a depth limit, and enables polymorphic tool matching.

  # ── 1. Schema validation ──────────────────────────────────

  Scenario: YAML with inherits field parses correctly
    Given a type-inherit YAML string with inherits "container-instance"
    When I parse the type-inherit YAML via ResourceTypeConfigSchema
    Then the type-inherit schema inherits field is "container-instance"

  Scenario: YAML with inherits set to null parses as root type
    Given a type-inherit YAML string with no inherits
    When I parse the type-inherit YAML via ResourceTypeConfigSchema
    Then the type-inherit schema inherits field is null

  Scenario: Schema rejects self-inheritance
    Given a type-inherit YAML string where name equals inherits "acme/looper"
    When I attempt to parse the type-inherit YAML expecting an error
    Then the type-inherit parse error mentions "inherit from itself"

  Scenario: Schema rejects built-in inheriting from custom type
    Given a type-inherit built-in YAML inheriting from custom "acme/custom-rt"
    When I attempt to parse the type-inherit YAML expecting an error
    Then the type-inherit parse error mentions "cannot inherit from custom"

  Scenario: YAML with replace flags parses correctly
    Given a type-inherit YAML string with cli_args_replace true
    When I parse the type-inherit YAML via ResourceTypeConfigSchema
    Then the type-inherit schema cli_args_replace is true

  # ── 2. Field resolution ───────────────────────────────────

  Scenario: Scalar fields in subtype override parent
    Given a type-inherit registry with parent "container-instance" description "Parent desc"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" with description "Child desc"
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved description is "Child desc"

  Scenario: Scalar fields fall through from parent when absent in child
    Given a type-inherit registry with parent "container-instance" having handler "parent.Handler"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" without handler
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved handler is "parent.Handler"

  # ── 3. Collection merging ─────────────────────────────────

  Scenario: cli_args additive merge — parent args preserved, child appended
    Given a type-inherit parent "container-instance" with cli_args "path,port"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" with cli_args "env"
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved cli_args names are "path, port, env"

  Scenario: cli_args same-name replacement during merge
    Given a type-inherit parent "container-instance" with cli_args "path,port"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" with cli_args "port"
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved cli_args count is 2
    And the type-inherit resolved cli_args names are "path, port"

  Scenario: cli_args replace mode replaces parent entirely
    Given a type-inherit parent "container-instance" with cli_args "path,port"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" with cli_args "env" and cli_args_replace
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved cli_args names are "env"

  Scenario: child_types additive merge — union deduplication
    Given a type-inherit parent "container-instance" with child_types "fs-directory,fs-file"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" with child_types "fs-file,fs-mount"
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved child_types are "fs-directory, fs-file, fs-mount"

  Scenario: child_types replace mode replaces parent entirely
    Given a type-inherit parent "container-instance" with child_types "fs-directory,fs-file"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" with child_types "fs-mount" and child_types_replace
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved child_types are "fs-mount"

  Scenario: parent_types additive merge
    Given a type-inherit parent "container-instance" with parent_types "git-checkout"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" with parent_types "fs-mount"
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved parent_types are "git-checkout, fs-mount"

  Scenario: parent_types replace mode
    Given a type-inherit parent "container-instance" with parent_types "git-checkout"
    And a type-inherit child "acme/my-container" inheriting from "container-instance" with parent_types "fs-mount" and parent_types_replace
    When I resolve type-inherit fields for "acme/my-container"
    Then the type-inherit resolved parent_types are "fs-mount"

  # ── 4. Chain resolution ───────────────────────────────────

  Scenario: Single-level inheritance chain resolution
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/devcontainer" inheriting from "container-instance"
    When I resolve the type-inherit chain for "acme/devcontainer"
    Then the type-inherit chain is "acme/devcontainer, container-instance"

  Scenario: Multi-level inheritance chain resolution
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/app-container" inheriting from "container-instance"
    And a type-inherit type "acme/web-container" inheriting from "acme/app-container"
    When I resolve the type-inherit chain for "acme/web-container"
    Then the type-inherit chain is "acme/web-container, acme/app-container, container-instance"

  Scenario: Root type chain is just itself
    Given a type-inherit registry with "container-instance" as root
    When I resolve the type-inherit chain for "container-instance"
    Then the type-inherit chain is "container-instance"

  Scenario: validate_chain succeeds for valid chain
    Given a type-inherit registry with "container-instance" as root
    When I validate type-inherit chain for "acme/devcontainer" inheriting "container-instance"
    Then the type-inherit validated chain is "acme/devcontainer, container-instance"

  Scenario: validate_chain rejects missing parent
    Given a type-inherit registry with "container-instance" as root
    When I validate type-inherit chain for "acme/devcontainer" inheriting "nonexistent" expecting error
    Then the type-inherit validation error is ResourceTypeParentNotFoundError

  # ── 5. Polymorphism ───────────────────────────────────────

  Scenario: is_subtype_of returns true for direct child
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/devcontainer" inheriting from "container-instance"
    When I check type-inherit is_subtype_of "acme/devcontainer" and "container-instance"
    Then the type-inherit subtype check is true

  Scenario: is_subtype_of returns true for same type
    Given a type-inherit registry with "container-instance" as root
    When I check type-inherit is_subtype_of "container-instance" and "container-instance"
    Then the type-inherit subtype check is true

  Scenario: is_subtype_of returns false for unrelated types
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit registry also has "git-checkout" as root
    When I check type-inherit is_subtype_of "container-instance" and "git-checkout"
    Then the type-inherit subtype check is false

  Scenario: is_subtype_of returns true for transitive ancestor
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/app-container" inheriting from "container-instance"
    And a type-inherit type "acme/web-container" inheriting from "acme/app-container"
    When I check type-inherit is_subtype_of "acme/web-container" and "container-instance"
    Then the type-inherit subtype check is true

  Scenario: Tool bound to parent matches subtype resource
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/devcontainer" inheriting from "container-instance"
    And a type-inherit tool "ns/deploy" bound to resource type "container-instance"
    When I find type-inherit tools for resource type "acme/devcontainer"
    Then the type-inherit matched tools include "ns/deploy"

  Scenario: Tool bound to child does not match parent resource
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/devcontainer" inheriting from "container-instance"
    And a type-inherit tool "ns/special" bound to resource type "acme/devcontainer"
    When I find type-inherit tools for resource type "container-instance"
    Then the type-inherit matched tools list is empty

  Scenario: find_subtypes returns all descendants
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/app-container" inheriting from "container-instance"
    And a type-inherit type "acme/web-container" inheriting from "acme/app-container"
    When I find type-inherit subtypes of "container-instance"
    Then the type-inherit subtypes include "acme/app-container"
    And the type-inherit subtypes include "acme/web-container"

  # ── 6. Cycle detection ────────────────────────────────────

  Scenario: Circular two-type cycle is rejected
    Given a type-inherit registry with "acme/alpha" inheriting from "acme/beta"
    And a type-inherit registry with "acme/beta" inheriting from "acme/alpha"
    When I resolve the type-inherit chain for "acme/alpha" expecting error
    Then the type-inherit chain error is ResourceTypeCircularInheritanceError

  # ── 7. Depth limit ────────────────────────────────────────

  Scenario: Chain exceeding MAX_CHAIN_DEPTH is rejected
    Given a type-inherit registry with a chain of depth 6
    When I resolve the type-inherit chain for the deepest type expecting error
    Then the type-inherit chain error is ResourceTypeInheritanceDepthError

  Scenario: Chain at exactly MAX_CHAIN_DEPTH succeeds
    Given a type-inherit registry with a chain of depth 5
    When I resolve the type-inherit chain for the deepest type
    Then the type-inherit chain length is 5

  # ── 8. Parent removal guard ───────────────────────────────

  Scenario: Parent type with subtypes cannot be removed
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/devcontainer" inheriting from "container-instance"
    When I attempt to type-inherit remove "container-instance"
    Then the type-inherit removal error is ResourceTypeParentRemovalError

  # ── 9. Additional coverage ────────────────────────────────

  Scenario: Circular three-type cycle is rejected
    Given a type-inherit registry with "acme/alpha" inheriting from "acme/beta"
    And a type-inherit registry with "acme/beta" inheriting from "acme/gamma"
    And a type-inherit registry with "acme/gamma" inheriting from "acme/alpha"
    When I resolve the type-inherit chain for "acme/alpha" expecting error
    Then the type-inherit chain error is ResourceTypeCircularInheritanceError

  Scenario: Three-level field merge — grandchild overrides child and inherits root
    Given a type-inherit parent "container-instance" with cli_args "path,port"
    And a type-inherit child "acme/app-container" inheriting from "container-instance" with cli_args "env"
    And a type-inherit grandchild "acme/web-container" inheriting from "acme/app-container" with cli_args "host"
    When I resolve type-inherit fields for "acme/web-container"
    Then the type-inherit resolved cli_args names are "path, port, env, host"

  Scenario: resolve_handler_polymorphic falls back to ancestor handler
    Given a type-inherit registry with "container-instance" as root with handler "cleveragents.resource.handlers.fs_directory:FsDirectoryHandler"
    And a type-inherit type "acme/devcontainer" inheriting from "container-instance"
    When I resolve type-inherit handler polymorphic for "acme/devcontainer"
    Then the type-inherit resolved handler is not None

  Scenario: validate_chain rejects built-in type inheriting custom parent
    Given a type-inherit registry with "acme/custom-parent" as root
    When I validate type-inherit chain for built-in "my-builtin" inheriting "acme/custom-parent" expecting error
    Then the type-inherit validation error is ValueError

  # ── 10. Coverage: edge cases ──────────────────────────────

  Scenario: Chain resolution raises ParentNotFoundError for missing parent
    Given a type-inherit registry with "acme/child" inheriting from "acme/missing"
    When I resolve the type-inherit chain for "acme/child" expecting error
    Then the type-inherit chain error is ResourceTypeParentNotFoundError

  Scenario: Chain resolution returns singleton for unregistered type
    When I resolve the type-inherit chain for "acme/never-registered"
    Then the type-inherit chain is "acme/never-registered"

  Scenario: validate_chain returns singleton when inherits is None
    Given a type-inherit registry with "container-instance" as root
    When I validate type-inherit chain for "acme/standalone" inheriting nothing
    Then the type-inherit validated chain is "acme/standalone"

  Scenario: is_subtype_of returns false when chain has errors
    Given a type-inherit registry with "acme/broken" inheriting from "acme/missing"
    When I check type-inherit is_subtype_of "acme/broken" and "acme/missing"
    Then the type-inherit subtype check is false

  Scenario: resolve_fields with root-only type returns its own fields
    Given a type-inherit registry with parent "container-instance" description "Root container type"
    When I resolve type-inherit fields for "container-instance"
    Then the type-inherit resolved description is "Root container type"

  Scenario: _get_inherits works with object-style entries
    Given a type-inherit registry with object-style entry "acme/obj-child" inheriting "container-instance"
    And a type-inherit registry with "container-instance" as root
    When I resolve the type-inherit chain for "acme/obj-child"
    Then the type-inherit chain is "acme/obj-child, container-instance"

  Scenario: _to_dict works with Pydantic model_dump entries
    Given a type-inherit registry with pydantic-style entry "acme/pydantic-type" having description "Pydantic type"
    When I resolve type-inherit fields for "acme/pydantic-type"
    Then the type-inherit resolved description is "Pydantic type"

  Scenario: _merge_cli_args returns child when parent has no args
    Given a type-inherit parent "empty-parent" with no cli_args
    And a type-inherit child "acme/child-only" inheriting from "empty-parent" with cli_args "path"
    When I resolve type-inherit fields for "acme/child-only"
    Then the type-inherit resolved cli_args names are "path"

  Scenario: _merge_cli_args returns parent when child has no args
    Given a type-inherit parent "container-instance" with cli_args "path,port"
    And a type-inherit child "acme/bare-child" inheriting from "container-instance" with no cli_args
    When I resolve type-inherit fields for "acme/bare-child"
    Then the type-inherit resolved cli_args names are "path, port"

  Scenario: resolve_handler_polymorphic raises when no handler in chain
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit type "acme/no-handler" inheriting from "container-instance"
    When I resolve type-inherit handler polymorphic for "acme/no-handler" expecting error
    Then the type-inherit handler error is HandlerResolutionError

  Scenario: Tool registry duplicate add raises ToolError
    Given a type-inherit tool registry with tool "ns/dup-tool" bound to "container-instance"
    When I add type-inherit tool "ns/dup-tool" again expecting error
    Then the type-inherit tool error is ToolError

  Scenario: Tool registry get returns None for unknown tool
    Given a type-inherit empty tool registry
    When I get type-inherit tool "ns/unknown"
    Then the type-inherit tool result is None

  Scenario: Tool registry list_tools with namespace filter
    Given a type-inherit tool registry with tool "ns/tool-a" bound to "container-instance"
    And a type-inherit tool registry with tool "other/tool-b" bound to "git-checkout"
    When I list type-inherit tools with namespace "ns"
    Then the type-inherit tools list has 1 entry

  Scenario: Tool registry remove returns true for existing tool
    Given a type-inherit tool registry with tool "ns/to-remove" bound to "container-instance"
    When I remove type-inherit tool "ns/to-remove"
    Then the type-inherit tool remove result is true

  Scenario: Tool registry remove returns false for missing tool
    Given a type-inherit empty tool registry
    When I remove type-inherit tool "ns/nonexistent"
    Then the type-inherit tool remove result is false

  Scenario: find_tools_for_resource skips tools with no bindings
    Given a type-inherit registry with "container-instance" as root
    And a type-inherit tool registry with unbound tool "ns/no-bindings"
    When I find type-inherit tools for resource type "container-instance"
    Then the type-inherit matched tools list is empty

  Scenario: Tool registry list_tools with source filter
    Given a type-inherit tool registry with tool "ns/tool-x" bound to "container-instance"
    When I list type-inherit tools with source "test"
    Then the type-inherit tools list has 1 entry

  Scenario: resolve_handler raises on empty reference
    When I resolve type-inherit handler with empty reference expecting error
    Then the type-inherit handler error is HandlerResolutionError

  Scenario: resolve_handler raises on missing module
    When I resolve type-inherit handler with reference "nonexistent.module:Cls" expecting error
    Then the type-inherit handler error is HandlerResolutionError

  Scenario: resolve_handler raises on missing class
    When I resolve type-inherit handler with reference "cleveragents.resource.handlers.fs_directory:NonexistentClass" expecting error
    Then the type-inherit handler error is HandlerResolutionError

  Scenario: resolve_handler raises on malformed colon-only reference
    When I resolve type-inherit handler with reference ":ClassName" expecting error
    Then the type-inherit handler error is HandlerResolutionError

  # -- F26: whitespace-only inherits validation --------------------------------

  Scenario: validate_chain rejects whitespace-only inherits value
    Given a type-inherit registry with "base" as root
    When I validate type-inherit chain for "acme/child" inheriting "   " expecting error
    Then the type-inherit validation error is ValueError

  # -- F18: side-effect verification after error scenarios ---------------------

  Scenario: registry is unchanged after circular inheritance error
    Given a type-inherit registry with "A" inheriting from "B"
    And a type-inherit registry with "B" inheriting from "A"
    When I resolve the type-inherit chain for "A" expecting error
    Then the type-inherit chain error is ResourceTypeCircularInheritanceError
    And the type-inherit registry still contains "A"
    And the type-inherit registry still contains "B"

  Scenario: registry is unchanged after depth limit error
    Given a type-inherit registry with a chain of depth 6
    When I resolve the type-inherit chain for the deepest type expecting error
    Then the type-inherit chain error is ResourceTypeInheritanceDepthError
    And the type-inherit registry size is 6

  # -- F5/AC-7: CLI type list shows Inherits column ----------------------------

  Scenario: CLI type list displays Inherits column for child types
    Given a mock service with parent "container-instance" and child "acme/docker-app"
    When I invoke "type list" via CliRunner
    Then the CLI output contains "Inherits"
    And the CLI output contains "container-instance"
    And the CLI exit code is 0

  # -- F5/AC-6: CLI type show displays inheritance chain -----------------------

  Scenario: CLI type show displays inheritance chain for child type
    Given a mock service with type "acme/docker-app" inheriting "container-instance"
    And the mock service resolves chain "acme/docker-app, container-instance"
    When I invoke "type show acme/docker-app" via CliRunner
    Then the CLI output contains "Inheritance Chain"
    And the CLI output contains "acme/docker-app -> container-instance"
    And the CLI exit code is 0
