Feature: Built-in File Tools
  As a developer
  I want built-in file operation tools
  So that agents can read, write, edit, delete, list, and search files safely

  # ---- File Read ----

  Scenario: Read a file with default encoding
    Given a temporary sandbox directory
    And a file "hello.txt" with content "Hello, World!"
    When I execute the "builtin/file-read" tool with path "hello.txt"
    Then the tool result should be successful
    And the output "content" should be "Hello, World!"
    And the output "encoding" should be "utf-8"
    And the output "size" should be greater than 0

  Scenario: Read a file with offset and limit
    Given a temporary sandbox directory
    And a file "lines.txt" with lines "line1,line2,line3,line4,line5"
    When I execute the "builtin/file-read" tool with path "lines.txt" offset 1 limit 2
    Then the tool result should be successful
    And the output "content" should contain "line2"
    And the output "content" should contain "line3"
    And the output "content" should not contain "line1"

  # ---- File Write ----

  Scenario: Write a new file
    Given a temporary sandbox directory
    When I execute the "builtin/file-write" tool with path "new.txt" and content "created"
    Then the tool result should be successful
    And the output "created" should be boolean true
    And the output "size" should be greater than 0
    And the file "new.txt" should exist in the sandbox

  Scenario: Overwrite an existing file
    Given a temporary sandbox directory
    And a file "existing.txt" with content "old content"
    When I execute the "builtin/file-write" tool with path "existing.txt" and content "new content"
    Then the tool result should be successful
    And the output "created" should be boolean false

  Scenario: Write file creates parent directories
    Given a temporary sandbox directory
    When I execute the "builtin/file-write" tool with path "sub/dir/file.txt" and content "nested"
    Then the tool result should be successful
    And the file "sub/dir/file.txt" should exist in the sandbox

  # ---- File Edit ----

  Scenario: Edit file with single replacement
    Given a temporary sandbox directory
    And a file "edit.txt" with content "foo bar foo"
    When I execute the "builtin/file-edit" tool replacing "foo" with "baz"
    Then the tool result should be successful
    And the output "replacements" should equal 1

  Scenario: Edit file with replace_all
    Given a temporary sandbox directory
    And a file "edit.txt" with content "foo bar foo"
    When I execute the "builtin/file-edit" tool replacing all "foo" with "baz"
    Then the tool result should be successful
    And the output "replacements" should equal 2

  Scenario: Edit file with old_text not found raises error
    Given a temporary sandbox directory
    And a file "edit.txt" with content "foo bar"
    When I execute the "builtin/file-edit" tool replacing "notfound" with "baz"
    Then the tool result should not be successful
    And the tool result error should mention "not found"

  # ---- File Delete ----

  Scenario: Delete an existing file
    Given a temporary sandbox directory
    And a file "delete-me.txt" with content "doomed"
    When I execute the "builtin/file-delete" tool with path "delete-me.txt"
    Then the tool result should be successful
    And the output "existed" should be boolean true
    And the file "delete-me.txt" should not exist in the sandbox

  Scenario: Delete a nonexistent file
    Given a temporary sandbox directory
    When I execute the "builtin/file-delete" tool with path "ghost.txt"
    Then the tool result should be successful
    And the output "existed" should be boolean false

  # ---- File List ----

  Scenario: List directory contents
    Given a temporary sandbox directory
    And a file "a.txt" with content "a"
    And a file "b.py" with content "b"
    When I list directory "." with the file-list tool
    Then the tool result should be successful
    And the output files list should contain at least 2 entries

  Scenario: List directory with pattern filter
    Given a temporary sandbox directory
    And a file "a.txt" with content "a"
    And a file "b.py" with content "b"
    When I list directory "." filtering by pattern "*.txt"
    Then the tool result should be successful
    And all listed files should match pattern "*.txt"

  Scenario: List directory recursively
    Given a temporary sandbox directory
    And a file "sub/deep.txt" with content "deep"
    When I list directory "." recursively with the file-list tool
    Then the tool result should be successful
    And the output files list should contain at least 1 entries

  # ---- File Search ----

  Scenario: Search files for pattern
    Given a temporary sandbox directory
    And a file "haystack.txt" with content "needle in a haystack"
    When I search directory "." for pattern "needle"
    Then the tool result should be successful
    And the search matches should contain at least 1 result

  Scenario: Search with max_results limit
    Given a temporary sandbox directory
    And a file "many.txt" with lines "match,match,match,match,match"
    When I search directory "." for pattern "match" with max_results 2
    Then the tool result should be successful
    And the search matches should contain exactly 2 results

  # ---- Path Traversal Prevention ----

  Scenario: Path traversal with dotdot is rejected
    Given a temporary sandbox directory
    When I execute the "builtin/file-read" tool with path "../../etc/passwd"
    Then the tool result should not be successful
    And the tool result error should mention "traversal"

  Scenario: Path traversal in write is rejected
    Given a temporary sandbox directory
    When I execute the "builtin/file-write" tool with path "../escape.txt" and content "evil"
    Then the tool result should not be successful
    And the tool result error should mention "traversal"

  Scenario: Path traversal in delete is rejected
    Given a temporary sandbox directory
    When I execute the "builtin/file-delete" tool with path "../../etc/passwd"
    Then the tool result should not be successful
    And the tool result error should mention "traversal"

  # ---- ChangeSet Capture ----

  Scenario: ChangeSet captures write operations
    Given a temporary sandbox directory
    And a changeset capture with plan_id "plan-001"
    When I write a file through changeset-wrapped tools
    Then the changeset should have 1 entry
    And the changeset entry operation should be "create"

  Scenario: ChangeSet captures edit operations
    Given a temporary sandbox directory
    And a file "cs-edit.txt" with content "hello world"
    And a changeset capture with plan_id "plan-002"
    When I edit a file through changeset-wrapped tools
    Then the changeset should have 1 entry
    And the changeset entry operation should be "modify"

  Scenario: ChangeSet captures delete operations
    Given a temporary sandbox directory
    And a file "cs-delete.txt" with content "bye"
    And a changeset capture with plan_id "plan-003"
    When I delete a file through changeset-wrapped tools
    Then the changeset should have 1 entry
    And the changeset entry operation should be "delete"

  Scenario: ChangeSet summary generation
    Given a temporary sandbox directory
    And a changeset capture with plan_id "plan-004"
    When I perform multiple changeset-tracked operations
    Then the changeset summary should mention the total count
    And the changeset summary should mention operation types

  Scenario: ChangeSet clear resets tracking
    Given a temporary sandbox directory
    And a changeset capture with plan_id "plan-005"
    When I write a file through changeset-wrapped tools
    And I clear the changeset
    Then the changeset should have 0 entries

  Scenario: Empty changeset summary
    Given a changeset capture with plan_id "plan-empty"
    Then the changeset summary should be "No changes recorded"

  # ---- Tool Registration Helper ----

  Scenario: Register all file tools
    Given a tool registry
    When I register all file tools
    Then the registry should contain 6 tools
    And the registry should contain tool "builtin/file-read"
    And the registry should contain tool "builtin/file-write"
    And the registry should contain tool "builtin/file-edit"
    And the registry should contain tool "builtin/file-delete"
    And the registry should contain tool "builtin/file-list"
    And the registry should contain tool "builtin/file-search"

  Scenario: Register file tools with changeset
    Given a tool registry
    And a changeset capture with plan_id "plan-reg"
    When I register file tools with changeset
    Then the registry should contain 6 tools

  # ---- ChangeSet model fields ----

  Scenario: ChangeSetEntry stores before and after hashes
    Given a temporary sandbox directory
    And a file "hash-test.txt" with content "original"
    And a changeset capture with plan_id "plan-hash"
    When I edit "hash-test.txt" through changeset-wrapped tools
    Then the changeset entry should have a before_hash
    And the changeset entry should have an after_hash
    And the before_hash and after_hash should differ

  Scenario: File list on non-directory raises error
    Given a temporary sandbox directory
    And a file "notadir.txt" with content "x"
    When I list directory "notadir.txt" with the file-list tool
    Then the tool result should not be successful
    And the tool result error should mention "not a directory"

  Scenario: File search on non-directory raises error
    Given a temporary sandbox directory
    And a file "notadir.txt" with content "x"
    When I search directory "notadir.txt" for pattern "x"
    Then the tool result should not be successful
    And the tool result error should mention "not a directory"

  Scenario: File search skips directories in results
    Given a temporary sandbox directory
    And a subdirectory "subdir" in the sandbox
    And a file "subdir/content.txt" with content "findme"
    When I search directory "." for pattern "findme"
    Then the tool result should be successful
    And the search matches should contain at least 1 result

  Scenario: ChangeSet detect_operation fallback create
    Given a temporary sandbox directory
    And a changeset capture with plan_id "plan-fallback"
    When I write a new file through raw changeset capture
    Then the changeset entry operation should be "create"

  Scenario: ChangeSet detect_operation fallback modify
    Given a temporary sandbox directory
    And a file "existing-cs.txt" with content "some content"
    And a changeset capture with plan_id "plan-modify-fallback"
    When I overwrite a file through raw changeset capture
    Then the changeset entry operation should be "modify"
