// AppFileGateway — AppRunner のファイル I/O を抽象化する。
//
// AppRunner は同じサンドボックス iframe + postMessage ブリッジを、認証版（スペース
// API・書き込み可）と公開版（app-share トークン API・read-only）の両方で使い回す。
// その差分を吸収するのがこの gateway。
//
// READ-ONLY の表現:
//   read-only は writeFile/deleteFile プロパティの「不在」で表す（実行時 false を返す
//   メソッドではない）。AppRunner は `gateway.writeFile` が undefined かどうかで書き込み
//   経路の有無を判定する。公開版は両メソッドを持たず、ブリッジが read-only エラーを返す。
//   サーバ側でも公開 API は GET のみなので、これは UI 側の二重防御に過ぎない。

import {
  fetchSpaceFileContent,
  fetchSpaceFiles,
  getSpaceFileRawUrl,
  writeSpaceFile,
  deleteSpaceFiles,
  fetchAppShareFileContent,
  fetchAppShareFiles,
  getAppShareRawUrl,
  type LocalFileEntry,
} from '../../api';

export interface AppFileGateway {
  /** テキスト読み取り（workspace 相対パス）。 */
  fetchContent(path: string): Promise<string>;
  /** ディレクトリ一覧（workspace 相対パス）。 */
  listFiles(dir: string): Promise<{ entries: LocalFileEntry[] }>;
  /** raw アセット URL（rewriteRelativeAssets / img src 用）。 */
  rawUrl(path: string): string;
  /** 書き込み（read-only gateway では未定義）。 */
  writeFile?(path: string, content: string): Promise<{ ok: boolean }>;
  /** 削除（read-only gateway では未定義）。 */
  deleteFile?(path: string): Promise<{ ok: boolean }>;
}

/** 認証版（スペース API）。write/delete あり。 */
export function createSpaceGateway(spaceId: string): AppFileGateway {
  return {
    fetchContent: (path) => fetchSpaceFileContent(spaceId, path),
    listFiles: (dir) => fetchSpaceFiles(spaceId, dir),
    rawUrl: (path) => getSpaceFileRawUrl(spaceId, path),
    async writeFile(path, content) {
      await writeSpaceFile(spaceId, path, { content });
      return { ok: true };
    },
    async deleteFile(path) {
      await deleteSpaceFiles(spaceId, [path]);
      return { ok: true };
    },
  };
}

/** 公開版（app-share トークン API）。read-only=write/delete は未定義。 */
export function createPublicAppGateway(token: string): AppFileGateway {
  return {
    fetchContent: (path) => fetchAppShareFileContent(token, path),
    listFiles: (dir) => fetchAppShareFiles(token, dir),
    rawUrl: (path) => getAppShareRawUrl(token, path),
    // writeFile / deleteFile はあえて未定義（read-only）。
  };
}
