/** Remote files over SFTP, the safe remote editor and the Transfer Manager (`files.*`). */
import { call, subscribeStrict } from "../transport";
import type { Payload, SudoOptions } from "../types";

type Ids = string | string[] | "all";
type Options = SudoOptions & Payload;

export const transfers = Object.freeze({
  list: () => call<Payload>("module_transfers_list", "plugin:files:transfers:list"),
  planUpload: (sessionId: string, directory: string, options: Options = {}) => call<Payload>("module_transfers_plan_upload", "plugin:files:transfers:planUpload", { sessionId, directory, options }),
  planCopy: (source: Payload, destination: Payload, options: Options = {}) => call<Payload>("module_transfers_plan_copy", "plugin:files:transfers:planCopy", { source, destination, options }),
  planDownload: (sessionId: string, paths: string[], options: Options = {}) => call<Payload>("module_transfers_plan_download", "plugin:files:transfers:planDownload", { sessionId, paths, options }),
  start: (planId: string, options: Options = {}) => call<Payload>("module_transfers_start", "plugin:files:transfers:start", { planId, options }),
  pause: (ids: Ids) => call<Payload>("module_transfers_pause", "plugin:files:transfers:pause", { ids }),
  resume: (ids: Ids, options: Options = {}) => call<Payload>("module_transfers_resume", "plugin:files:transfers:resume", { ids, options }),
  retry: (ids: Ids, options: Options = {}) => call<Payload>("module_transfers_retry", "plugin:files:transfers:retry", { ids, options }),
  cancel: (ids: Ids) => call<Payload>("module_transfers_cancel", "plugin:files:transfers:cancel", { ids }),
  remove: (ids: Ids) => call<Payload>("module_transfers_remove", "plugin:files:transfers:remove", { ids }),
  updateSettings: (settings: Payload) => call<Payload>("module_transfers_settings", "plugin:files:transfers:settings", { settings }),
  onUpdate: (callback: (update: Payload) => void) => subscribeStrict("module:files:transfers:update", callback, "Transfer")
});

/** Local disk of this computer (`files.local`, File Manager only). */
export const local = Object.freeze({
  places: () => call<Payload>("module_local_places", "plugin:files:local:places"),
  list: (path: string) => call<Payload[]>("module_local_list", "plugin:files:local:list", { path }),
  mkdir: (parent: string, name: string) => call<Payload>("module_local_mkdir", "plugin:files:local:mkdir", { parent, name }),
  createFile: (parent: string, name: string) => call<Payload>("module_local_create_file", "plugin:files:local:createFile", { parent, name }),
  rename: (path: string, name: string) => call<Payload>("module_local_rename", "plugin:files:local:rename", { path, name }),
  remove: (paths: string[]) => call<Payload>("module_local_remove", "plugin:files:local:remove", { paths })
});

export const files = Object.freeze({
  list: (sessionId: string, path: string, options: Options = {}) => call<Payload>("module_files_list", "plugin:files:list", { sessionId, path, options }),
  privileges: (sessionId: string) => call<Payload>("module_files_privileges", "plugin:files:privileges", { sessionId }),
  readText: (sessionId: string, path: string, options: Options = {}) => call<Payload>("module_files_read_text", "plugin:files:readText", { sessionId, path, options }),
  writeText: (sessionId: string, path: string, text: string, options: Options = {}) => call<Payload>("module_files_write_text", "plugin:files:writeText", { sessionId, path, text, options }),
  saveText: (sessionId: string, path: string, text: string, options: Options = {}) => call<Payload>("module_files_save_text", "plugin:files:saveText", { sessionId, path, text, options }),
  listRecovery: (sessionId: string, options: Options = {}) => call<Payload>("module_files_list_recovery", "plugin:files:listRecovery", { sessionId, options }),
  readRecovery: (sessionId: string, recoveryId: string, options: Options = {}) => call<Payload>("module_files_read_recovery", "plugin:files:readRecovery", { sessionId, recoveryId, options }),
  cleanupRecovery: (sessionId: string, recoveryId: string, options: Options = {}) => call<Payload>("module_files_cleanup_recovery", "plugin:files:cleanupRecovery", { sessionId, recoveryId, options }),
  closeText: (editId: string) => call<Payload>("module_files_close_text", "plugin:files:closeText", { editId }),
  createFile: (sessionId: string, path: string, options: Options = {}) => call<Payload>("module_files_create_file", "plugin:files:createFile", { sessionId, path, options }),
  mkdir: (sessionId: string, path: string, options: Options = {}) => call<Payload>("module_files_mkdir", "plugin:files:mkdir", { sessionId, path, options }),
  rename: (sessionId: string, from: string, to: string, options: Options = {}) => call<Payload>("module_files_rename", "plugin:files:rename", { sessionId, from, to, options }),
  remove: (sessionId: string, path: string, options: Options = {}) => call<Payload>("module_files_remove", "plugin:files:remove", { sessionId, path, options }),
  removeMany: (sessionId: string, paths: string[], recursive = false, options: Options = {}) => call<Payload>("module_files_remove_many", "plugin:files:removeMany", { sessionId, paths, recursive, options }),
  upload: (sessionId: string, directory: string) => call<Payload>("module_files_upload", "plugin:files:upload", { sessionId, directory }),
  download: (sessionId: string, path: string) => call<Payload>("module_files_download", "plugin:files:download", { sessionId, path }),
  downloadMany: (sessionId: string, paths: string[]) => call<Payload>("module_files_download_many", "plugin:files:downloadMany", { sessionId, paths }),
  downloadArchive: (sessionId: string, paths: string[], format: "zip" | "tar" | "tar.gz") => call<Payload>("module_files_download_archive", "plugin:files:downloadArchive", { sessionId, paths, format }),
  transfers,
  local
});
