/**
 * Tauri adapter for the public plugin workspace/project-structure SDK facade
 * (#124 + #129). The commands are plugin-scoped even though the gateway is
 * frontend-internal: plugins only see the stable service methods.
 */

import { invoke } from "@tauri-apps/api/core";

import type {
  PluginProjectStructure,
  PluginWorkspaceBinaryFile,
  PluginWorkspaceDirectoryListing,
  PluginWorkspaceStat,
  PluginWorkspaceTextFile,
} from "@/domain";
import type {
  PluginProjectStructureQuery,
  PluginWorkspaceGateway,
  PluginWorkspacePathInput,
  PluginWorkspaceWriteBinaryInput,
  PluginWorkspaceWriteTextInput,
} from "@/ports";

type BinaryFileDto = Omit<PluginWorkspaceBinaryFile, "bytes"> & {
  bytes: number[] | Uint8Array;
};

function toByteArray(bytes: number[] | Uint8Array): Uint8Array {
  return bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
}

function normalizeBinaryFile(file: BinaryFileDto): PluginWorkspaceBinaryFile {
  return { ...file, bytes: toByteArray(file.bytes) };
}

function binaryInput(input: PluginWorkspaceWriteBinaryInput): {
  projectId: string;
  path: string;
  bytes: number[];
} {
  return {
    projectId: input.projectId,
    path: input.path,
    bytes: Array.from(input.bytes),
  };
}

export class TauriPluginWorkspaceGateway implements PluginWorkspaceGateway {
  readText(input: PluginWorkspacePathInput): Promise<PluginWorkspaceTextFile> {
    return invoke<PluginWorkspaceTextFile>("plugin_workspace_read_text", { input });
  }

  async readBinary(input: PluginWorkspacePathInput): Promise<PluginWorkspaceBinaryFile> {
    const file = await invoke<BinaryFileDto>("plugin_workspace_read_binary", { input });
    return normalizeBinaryFile(file);
  }

  async writeText(input: PluginWorkspaceWriteTextInput): Promise<void> {
    await invoke("plugin_workspace_write_text", { input });
  }

  async writeBinary(input: PluginWorkspaceWriteBinaryInput): Promise<void> {
    await invoke("plugin_workspace_write_binary", { input: binaryInput(input) });
  }

  listDir(input: PluginWorkspacePathInput): Promise<PluginWorkspaceDirectoryListing> {
    return invoke<PluginWorkspaceDirectoryListing>("plugin_workspace_list_dir", { input });
  }

  stat(input: PluginWorkspacePathInput): Promise<PluginWorkspaceStat> {
    return invoke<PluginWorkspaceStat>("plugin_workspace_stat", { input });
  }

  queryProjectStructure(input: PluginProjectStructureQuery): Promise<PluginProjectStructure> {
    return invoke<PluginProjectStructure>("plugin_query_project_structure", { input });
  }
}
