package wasi:cli@0.2.0;

interface environment {
  /// Get the POSIX-style environment variables.
  ///
  /// Each environment variable is provided as a pair of string variable names
  /// and string value.
  ///
  /// Morally, these are a value import, but until value imports are available
  /// in the component model, this import function should return the same
  /// values each time it is called.
  get-environment: func() -> list<tuple<string, string>>;

  /// Get the POSIX-style arguments to the program.
  get-arguments: func() -> list<string>;

  /// Return a path that programs should use as their initial current working
  /// directory, interpreting `.` as shorthand for this.
  initial-cwd: func() -> option<string>;
}

interface exit {
  /// Exit the current instance and any linked instances.
  exit: func(status: result);
}

interface run {
  /// Run the program.
  run: func() -> result;
}

interface stdin {
  use wasi:io/streams@0.2.0.{input-stream};

  get-stdin: func() -> input-stream;
}

interface stdout {
  use wasi:io/streams@0.2.0.{output-stream};

  get-stdout: func() -> output-stream;
}

interface stderr {
  use wasi:io/streams@0.2.0.{output-stream};

  get-stderr: func() -> output-stream;
}

/// Terminal input.
///
/// In the future, this may include functions for disabling echoing,
/// disabling input buffering so that keyboard events are sent through
/// immediately, querying supported features, and so on.
interface terminal-input {
  /// The input side of a terminal.
  resource terminal-input;
}

/// Terminal output.
///
/// In the future, this may include functions for querying the terminal
/// size, being notified of terminal size changes, querying supported
/// features, and so on.
interface terminal-output {
  /// The output side of a terminal.
  resource terminal-output;
}

/// An interface providing an optional `terminal-input` for stdin as a
/// link-time authority.
interface terminal-stdin {
  use terminal-input.{terminal-input};

  /// If stdin is connected to a terminal, return a `terminal-input` handle
  /// allowing further interaction with it.
  get-terminal-stdin: func() -> option<terminal-input>;
}

/// An interface providing an optional `terminal-output` for stdout as a
/// link-time authority.
interface terminal-stdout {
  use terminal-output.{terminal-output};

  /// If stdout is connected to a terminal, return a `terminal-output` handle
  /// allowing further interaction with it.
  get-terminal-stdout: func() -> option<terminal-output>;
}

/// An interface providing an optional `terminal-output` for stderr as a
/// link-time authority.
interface terminal-stderr {
  use terminal-output.{terminal-output};

  /// If stderr is connected to a terminal, return a `terminal-output` handle
  /// allowing further interaction with it.
  get-terminal-stderr: func() -> option<terminal-output>;
}

world imports {
  import environment;
  import exit;
  import wasi:io/error@0.2.0;
  import wasi:io/poll@0.2.0;
  import wasi:io/streams@0.2.0;
  import stdin;
  import stdout;
  import stderr;
  import terminal-input;
  import terminal-output;
  import terminal-stdin;
  import terminal-stdout;
  import terminal-stderr;
  import wasi:clocks/monotonic-clock@0.2.0;
  import wasi:clocks/wall-clock@0.2.0;
  import wasi:filesystem/types@0.2.0;
  import wasi:filesystem/preopens@0.2.0;
  import wasi:sockets/network@0.2.0;
  import wasi:sockets/instance-network@0.2.0;
  import wasi:sockets/udp@0.2.0;
  import wasi:sockets/udp-create-socket@0.2.0;
  import wasi:sockets/tcp@0.2.0;
  import wasi:sockets/tcp-create-socket@0.2.0;
  import wasi:sockets/ip-name-lookup@0.2.0;
  import wasi:random/random@0.2.0;
  import wasi:random/insecure@0.2.0;
  import wasi:random/insecure-seed@0.2.0;
}
world command {
  import environment;
  import exit;
  import wasi:io/error@0.2.0;
  import wasi:io/poll@0.2.0;
  import wasi:io/streams@0.2.0;
  import stdin;
  import stdout;
  import stderr;
  import terminal-input;
  import terminal-output;
  import terminal-stdin;
  import terminal-stdout;
  import terminal-stderr;
  import wasi:clocks/monotonic-clock@0.2.0;
  import wasi:clocks/wall-clock@0.2.0;
  import wasi:filesystem/types@0.2.0;
  import wasi:filesystem/preopens@0.2.0;
  import wasi:sockets/network@0.2.0;
  import wasi:sockets/instance-network@0.2.0;
  import wasi:sockets/udp@0.2.0;
  import wasi:sockets/udp-create-socket@0.2.0;
  import wasi:sockets/tcp@0.2.0;
  import wasi:sockets/tcp-create-socket@0.2.0;
  import wasi:sockets/ip-name-lookup@0.2.0;
  import wasi:random/random@0.2.0;
  import wasi:random/insecure@0.2.0;
  import wasi:random/insecure-seed@0.2.0;

  export run;
}
