var io = this

function remove_dir(path) {
  var files = io.enumerate(path, false)  // non-recursive first
  
  // Delete all files and subdirectories
  for (var i = 0; i < files.length; i++) {
    var file = files[i]
    if (io.is_directory(file)) {
      remove_dir(file)  // Recurse into subdirectory
    } else {
      try {
        io.rm(file)
      } catch (e) {
        log.error("Failed to remove " + file + ": " + e)
      }
    }
  }
  
  // Now remove the empty directory
  try {
    io.rm(path)
  } catch (e) {
    log.error("Failed to remove directory " + path + ": " + e)
  }
}

io.rmdir = remove_dir

io.rm[cell.DOC] = `Remove the file or empty directory at the given path.

:param path: The file or empty directory to remove. Must be empty if a directory.
:return: None
`

io.mkdir[cell.DOC] = `Create a directory at the given path.

:param path: The directory path to create.
:return: None
`

io.exists[cell.DOC] = `Return a boolean indicating whether the file or directory at the given path exists.

:param path: The file or directory path to check.
:return: True if the path exists, otherwise false.
`

io.stat[cell.DOC] = `Return an object describing file metadata for the given path. The object includes
filesize, modtime, createtime, and accesstime. Throw an error if the path does not exist.

:param path: The file or directory to retrieve metadata for.
:return: An object with metadata (filesize, modtime, createtime, accesstime).
`

io.slurpbytes[cell.DOC] = `Read the entire file at the given path as a raw ArrayBuffer. Throw on error.

:param path: The file path to read from.
:return: An ArrayBuffer containing the file’s raw bytes.
`

io.slurp[cell.DOC] = `Read the entire file at the given path as a string. Throw on error.

:param path: The file path to read from.
:return: A string with the file’s contents.
`

io.slurpwrite[cell.DOC] = `Write data (string or ArrayBuffer) to the given file path. Overwrite if it exists.
Throw on error.

:param data: The data to write (string or ArrayBuffer).
:param path: The file path to write to.
:return: None
`

io.mount[cell.DOC] = `Mount a directory or archive at the specified mount point. An null mount
point mounts to '/'. Throw on error.

:param archiveOrDir: The directory or archive to mount.
:param mountPoint: The path at which to mount. If omitted or null, '/' is used.
:return: None
`

io.unmount[cell.DOC] = `Unmount a previously mounted directory or archive. Throw on error.

:param path: The directory or archive mount point to unmount.
:return: None
`

io.writepath[cell.DOC] = `Set the write directory. Subsequent writes will go here by default. Throw on error.

:param path: The directory path to set as writable.
:return: None
`

io.match[cell.DOC] = `Return boolean indicating whether the given wildcard pattern matches the provided
string. Dots must match dots. Case is not ignored.

Patterns can incorporate:
'?'  - Matches exactly one character (except leading dots or slashes).
'*'  - Matches zero or more characters (excluding path separators).
'**' - Matches zero or more characters, including path separators.
'[abc]' - A bracket expression; matches any single character from the set. Ranges like [a-z], [0-9] also work.
'[[:alpha:]]' - POSIX character classes can be used inside brackets.
'\\' - Backslash escapes the next character.
'!'  - If placed immediately inside brackets (like [!abc]), it negates the set.

:param pattern: The wildcard pattern to compare.
:param string: The string to test against the wildcard pattern.
:return: True if matched, otherwise false.
`

io.globfs[cell.DOC] = `Return an array of files that do not match any of the provided glob patterns. It
recursively enumerates the filesystem within PHYSFS. Each pattern is treated as an
"ignore" rule, similar to .gitignore usage.

:param patterns: An array of glob patterns to ignore. Any file matching one of these is skipped.
:return: An array of matching file paths.
`

io.enumerate[cell.DOC] = `Return an array of files within the given directory, optionally recursing into
subdirectories.

:param path: The directory to list.
:param recurse: Whether to recursively include subdirectories (true or false).
:return: An array of file (and directory) paths found.
`

io.basedir[cell.DOC] = `Return the application's base directory (where the executable is located).

:return: A string with the base directory path.
`

io.prefdir[cell.DOC] = `Get the user-and-app-specific path where files can be written.

:param org: The name of your organization.
:param app: The name of your application.
:return: A string with the user's directory path.
`

io.open[cell.DOC] = `Open a file for writing, returning a file object that can be used for further
operations. Throw on error.

:param path: The file path to open for writing.
:return: A file object for subsequent write operations.
`

io.realdir[cell.DOC] = `Return the actual, real directory (on the host filesystem) that contains the given
file path. Return null if not found.

:param path: The file path whose real directory is requested.
:return: A string with the real directory path, or null.
`

io.searchpath[cell.DOC] = `Return an array of all directories in the current paths.

:return: An array of directory paths in the search path.
`

return io
