
@namespace("keybase.1")
protocol install {

  import idl "common.avdl";

  /**
    Install status describes state of install for a component or service.
    */
  @go("nostring")
  enum InstallStatus {
    UNKNOWN_0,
    ERROR_1,
    NOT_INSTALLED_2,
    INSTALLED_4
  }

  @go("nostring")
  enum InstallAction {
    UNKNOWN_0,
    NONE_1, // Nothing to do
    UPGRADE_2, // Upgrade from earlier version
    REINSTALL_3, // Something bad happened and need re-install
    INSTALL_4 // Installing (not installed)
  }

  record ServiceStatus {
    string version;
    string label;
    string pid;
    string lastExitStatus;
    string bundleVersion;
    InstallStatus installStatus;
    InstallAction installAction;
    Status status;
  }

  record ServicesStatus {
    array<ServiceStatus> service;
    array<ServiceStatus> kbfs;
    array<ServiceStatus> updater;
  }

  record FuseMountInfo {
    string path;
    string fstype;
    string output; // Output from mount, may be platform specific
  }

  record FuseStatus {
    string version;
    string bundleVersion;
    string kextID;
    string path;
    boolean kextStarted;
    InstallStatus installStatus;
    InstallAction installAction;
    array<FuseMountInfo> mountInfos;
    Status status;
  }

  record ComponentResult {
    string name;
    Status status;
    int exitCode;
  }

  record InstallResult {
    array<ComponentResult> componentResults;
    Status status;
    boolean fatal;
  }

  record UninstallResult {
    array<ComponentResult> componentResults;
    Status status;
  }

  /*
    Return status for Fuse install.
    If you specify bundleVersion, it will tell you if an upgrade is needed.
   */
  FuseStatus fuseStatus(int sessionID, string bundleVersion);

  /*
    Install Fuse.
   */
  InstallResult installFuse();

  /*
    Install KBFS (including mount).
   */
  InstallResult installKBFS();

  /*
    Uninstalls KBFS (and Fuse, mount).
   */
  UninstallResult uninstallKBFS();

  /*
    Install command line via privileged helper.
   */
  InstallResult installCommandLinePrivileged();
}
