// `type` is a single character following the conventions of the 'ls' command

export interface DirectoryEntryRegFile {
  type: '-';
  name: string;
  executable: boolean;
  hash: string;
}

export interface DirectoryEntryDir {
  type: 'd';
  name: string;
  hash: string;
}

export interface DirectoryEntrySymlink {
  type: 'l';
  name: string;
  target: string;
}

export type DirectoryEntry = DirectoryEntryRegFile | DirectoryEntryDir | DirectoryEntrySymlink;

export type DirectoryEntryWithPath = {
  entry: DirectoryEntry;
  path: string;
};

// Types for the batch put method

interface PutManyItemFileContents {
  type: 'fileContents';
  contents: string;
}

interface PutManyItemDirectoryContents {
  type: 'directoryContents';
  contents: DirectoryEntry[];
}

type PutManyItem = PutManyItemFileContents | PutManyItemDirectoryContents;

export interface PutManyRequestPayload {
  items: PutManyItem[];
}

export interface PutManyResponsePayload {
  items: { hash: string }[];
}

export interface GetManyRequestPayload {
  rootHash: string;
  paths: string[];
  /**
   * Maximum aggregate size of decoded file contents and serialized metadata in
   * the response.
   */
  maxBytes?: number;
  /**
   * Maximum number of requested objects plus entries nested in returned
   * directory listings.
   */
  maxObjects?: number;
}

export type GetManyItemPayload =
  | {
      type: 'directoryContents';
      path: string;
      hash: string;
      contents: DirectoryEntry[];
    }
  | {
      type: 'fileContents';
      path: string;
      hash: string;
      executable: boolean;
      contents: string;
    }
  | {
      type: 'symlink';
      path: string;
      target: string;
    };

export interface GetManyResponsePayload {
  items: GetManyItemPayload[];
}
