Feature: Resource CLI tree, inspect, link-child, and unlink-child commands
  As a CleverAgents user
  I want to view resource trees, inspect resources, and manage DAG edges via the CLI
  So that I can navigate and manipulate resource hierarchies

  Background:
    Given a fresh resource tree test registry

  # ---- Resource Tree ----

  Scenario: Tree of a resource with no children
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/root-repo" at "/tmp/root"
    When I display resource tree for "local/root-repo"
    Then the tree output should contain "local/root-repo"
    And the tree output should contain "git-checkout"

  Scenario: Tree of a resource with children shows hierarchy
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/parent-repo" at "/tmp/parent"
    And a resource tree resource "fs-directory" named "local/child-dir" at "/tmp/child"
    And resource tree child "local/child-dir" is linked to parent "local/parent-repo"
    When I display resource tree for "local/parent-repo"
    Then the tree output should contain "local/parent-repo"
    And the tree output should contain "local/child-dir"

  Scenario: Tree with depth limit of 1
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/deep-root" at "/tmp/deep"
    And a resource tree resource "fs-directory" named "local/deep-child" at "/tmp/dc"
    And a resource tree resource "fs-directory" named "local/deep-grandchild" at "/tmp/dgc"
    And resource tree child "local/deep-child" is linked to parent "local/deep-root"
    And resource tree child "local/deep-grandchild" is linked to parent "local/deep-child"
    When I display resource tree depth-limited to 1 for "local/deep-root"
    Then the tree output should contain "local/deep-child"
    And the tree output should not contain "local/deep-grandchild"

  Scenario: Tree with type filter
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/filter-root" at "/tmp/fr"
    And a resource tree resource "fs-directory" named "local/filter-dir" at "/tmp/fd"
    And resource tree child "local/filter-dir" is linked to parent "local/filter-root"
    When I display resource tree type-filtered to "fs-directory" for "local/filter-root"
    Then the tree output should contain "local/filter-dir"

  Scenario: Tree in JSON format
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/json-tree" at "/tmp/jt"
    When I display resource tree as "json" for "local/json-tree"
    Then the tree output should be valid JSON

  Scenario: Tree of non-existent resource fails
    When I display resource tree for "nonexistent-resource"
    Then the tree command should fail
    And the tree output should contain "not found"

  # ---- Deterministic ordering ----

  Scenario: Tree children are sorted by name
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/sort-root" at "/tmp/sr"
    And a resource tree resource "fs-directory" named "local/z-last" at "/tmp/zl"
    And a resource tree resource "fs-directory" named "local/a-first" at "/tmp/af"
    And resource tree child "local/z-last" is linked to parent "local/sort-root"
    And resource tree child "local/a-first" is linked to parent "local/sort-root"
    When I display resource tree for "local/sort-root"
    Then the tree output should show "local/a-first" before "local/z-last"

  # ---- Resource Inspect ----

  Scenario: Inspect a resource shows details
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/inspect-repo" at "/tmp/ir"
    When I run basic inspect on "local/inspect-repo"
    Then the tree output should contain "local/inspect-repo"
    And the tree output should contain "git-checkout"

  Scenario: Inspect with --tree shows children
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/inspect-parent" at "/tmp/ip"
    And a resource tree resource "fs-directory" named "local/inspect-child" at "/tmp/ic"
    And resource tree child "local/inspect-child" is linked to parent "local/inspect-parent"
    When I run inspect with subtree on "local/inspect-parent"
    Then the tree output should contain "local/inspect-child"

  Scenario: Inspect with --tree and no children
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/no-children" at "/tmp/nc"
    When I run inspect with subtree on "local/no-children"
    Then the tree output should contain "no children"

  Scenario: Inspect with --file for existing file
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/file-repo" at a temp directory
    And a temp file "hello.txt" with content "Hello World"
    When I run inspect with file "hello.txt" on "local/file-repo"
    Then the tree output should contain "Hello World"

  Scenario: Inspect with --file for missing file
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/no-file" at "/tmp/nf"
    When I run inspect with file "nonexistent.txt" on "local/no-file"
    Then the tree output should contain "not found"

  Scenario: Inspect in JSON format
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/json-inspect" at "/tmp/ji"
    When I run inspect formatted as "json" on "local/json-inspect"
    Then the tree output should be valid JSON

  Scenario: Inspect non-existent resource fails
    When I run basic inspect on "nonexistent-resource"
    Then the tree command should fail
    And the tree output should contain "not found"

  # ---- Resource link-child ----

  Scenario: Link child successfully
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/link-parent" at "/tmp/lp"
    And a resource tree resource "fs-directory" named "local/link-child" at "/tmp/lc"
    When I link DAG child "local/link-child" to parent "local/link-parent"
    Then the tree output should contain "Linked"

  Scenario: Link child in JSON format
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/json-parent" at "/tmp/jp"
    And a resource tree resource "fs-directory" named "local/json-child" at "/tmp/jc"
    When I link as "json" DAG child "local/json-child" to parent "local/json-parent"
    Then the tree output should be valid JSON
    And the tree output should contain "linked"

  Scenario: Link child with non-existent parent fails
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "fs-directory" named "local/orphan" at "/tmp/orph"
    When I link DAG child "local/orphan" to parent "nonexistent-parent"
    Then the tree command should fail
    And the tree output should contain "not found"

  Scenario: Link child with non-existent child fails
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/lonely-parent" at "/tmp/lonely"
    When I link DAG child "nonexistent-child" to parent "local/lonely-parent"
    Then the tree command should fail
    And the tree output should contain "not found"

  Scenario: Duplicate link fails
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/dup-parent" at "/tmp/dp"
    And a resource tree resource "fs-directory" named "local/dup-child" at "/tmp/dpc"
    And resource tree child "local/dup-child" is linked to parent "local/dup-parent"
    When I link DAG child "local/dup-child" to parent "local/dup-parent"
    Then the tree command should fail
    And the tree output should contain "already exists"

  Scenario: Cycle detection rejects link
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "fs-directory" named "local/cyc-a" at "/tmp/ca"
    And a resource tree resource "fs-directory" named "local/cyc-b" at "/tmp/cb"
    And resource tree child "local/cyc-b" is linked to parent "local/cyc-a"
    When I link DAG child "local/cyc-a" to parent "local/cyc-b"
    Then the tree command should fail
    And the tree output should contain "ycle"

  # ---- Resource unlink-child ----

  Scenario: Unlink child successfully
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/unlink-parent" at "/tmp/up"
    And a resource tree resource "fs-directory" named "local/unlink-child" at "/tmp/uc"
    And resource tree child "local/unlink-child" is linked to parent "local/unlink-parent"
    When I unlink DAG child "local/unlink-child" from parent "local/unlink-parent" confirmed
    Then the tree output should contain "Unlinked"

  Scenario: Unlink child in JSON format
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/json-unlp" at "/tmp/jul"
    And a resource tree resource "fs-directory" named "local/json-unlc" at "/tmp/juc"
    And resource tree child "local/json-unlc" is linked to parent "local/json-unlp"
    When I unlink as "json" DAG child "local/json-unlc" from parent "local/json-unlp" confirmed
    Then the tree output should be valid JSON
    And the tree output should contain "unlinked"

  Scenario: Unlink non-existent link fails
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/nolink-parent" at "/tmp/nlp"
    And a resource tree resource "fs-directory" named "local/nolink-child" at "/tmp/nlc"
    When I unlink DAG child "local/nolink-child" from parent "local/nolink-parent" confirmed
    Then the tree command should fail
    And the tree output should contain "not found"

  Scenario: Unlink aborted without yes flag
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/abort-parent" at "/tmp/ap"
    And a resource tree resource "fs-directory" named "local/abort-child" at "/tmp/ac"
    And resource tree child "local/abort-child" is linked to parent "local/abort-parent"
    When I unlink DAG child "local/abort-child" from parent "local/abort-parent" declined
    Then the tree command should fail

  # ---- Self-link rejection ----

  Scenario: Link child to itself is rejected
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "fs-directory" named "local/self-link" at "/tmp/sl"
    When I link DAG child "local/self-link" to parent "local/self-link"
    Then the tree command should fail
    And the tree output should contain "itself"

  # ---- get_children service method ----

  Scenario: Service get_children returns children sorted by name
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/gc-parent" at "/tmp/gcp"
    And a resource tree resource "fs-directory" named "local/gc-z-child" at "/tmp/gcz"
    And a resource tree resource "fs-directory" named "local/gc-a-child" at "/tmp/gca"
    And resource tree child "local/gc-z-child" is linked to parent "local/gc-parent"
    And resource tree child "local/gc-a-child" is linked to parent "local/gc-parent"
    When I get children of resource "local/gc-parent"
    Then the children list should have 2 items
    And the first child name should be "local/gc-a-child"

  Scenario: Service get_children returns auto-discovered children for directory
    Given resource tree built-in types are bootstrapped
    And a seeded directory exists at "/tmp/gcl"
    And a resource tree resource "fs-directory" named "local/gc-leaf" at "/tmp/gcl"
    When I get children of resource "local/gc-leaf"
    Then the children list should have at least 1 child

  # ---- Inspect with no properties ----

  Scenario: Inspect resource with no properties shows none
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/noprops" at "/tmp/np" with no properties
    When I run basic inspect on "local/noprops"
    Then the tree output should contain "none"

  # ---- File read edge cases ----

  Scenario: Inspect file on resource with no location shows no-location message
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/noloc" with no location
    When I run inspect with file "test.txt" on "local/noloc"
    Then the tree output should contain "no location"

  Scenario: Inspect file that cannot be read shows error message
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/badfile" at a temp directory
    And a temp file that is unreadable named "binary.dat"
    When I run inspect with file "binary.dat" on "local/badfile"
    Then the tree output should contain "error reading"

  # ---- CleverAgentsError catch blocks in CLI ----

  Scenario: Tree command handles generic CleverAgentsError
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/tree-err" at "/tmp/te"
    When I display resource tree for "local/tree-err" with a service error
    Then the tree command should fail
    And the tree output should contain "Error"

  Scenario: Inspect command handles generic CleverAgentsError
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/inspect-err" at "/tmp/ie"
    When I run inspect on "local/inspect-err" with a service error
    Then the tree command should fail
    And the tree output should contain "Error"

  Scenario: Link-child command handles generic CleverAgentsError
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/link-err-p" at "/tmp/lep"
    And a resource tree resource "fs-directory" named "local/link-err-c" at "/tmp/lec"
    When I link DAG child "local/link-err-c" to parent "local/link-err-p" with a service error
    Then the tree command should fail
    And the tree output should contain "Error"

  Scenario: Unlink-child command handles generic CleverAgentsError
    Given resource tree built-in types are bootstrapped
    And a resource tree resource "git-checkout" named "local/unlink-err-p" at "/tmp/uep"
    And a resource tree resource "fs-directory" named "local/unlink-err-c" at "/tmp/uec"
    And resource tree child "local/unlink-err-c" is linked to parent "local/unlink-err-p"
    When I unlink DAG child "local/unlink-err-c" from parent "local/unlink-err-p" with a service error
    Then the tree command should fail
    And the tree output should contain "Error"
