import {
  convexToJson,
  GenericId,
  jsonToConvex,
  Value,
} from "@convex-dev/common";
import { performSyscall } from "./syscall.js";
import { DatabaseReader, DatabaseWriter } from "../database.js";
import { QueryInitializerImpl } from "./query_impl.js";
import { GenericDataModel, GenericDocument } from "../data_model.js";

export function setupReader(): DatabaseReader<GenericDataModel> {
  return {
    get: (id: GenericId<string>) => {
      const syscallJSON = performSyscall("get", { id: convexToJson(id) });
      const syscallResult = jsonToConvex(syscallJSON) as GenericDocument;
      return Promise.resolve(syscallResult);
    },
    query: (tableName: string) => new QueryInitializerImpl(tableName),
  };
}

export function setupWriter(): DatabaseWriter<GenericDataModel> {
  const reader = setupReader();
  return {
    get: reader.get,
    query: reader.query,

    insert: (table, value) => {
      const syscallJSON = performSyscall("insert", {
        table,
        value: convexToJson(value),
      });
      const syscallResult = jsonToConvex(syscallJSON) as any;
      return Promise.resolve(syscallResult._id);
    },
    patch: (id, value) => {
      performSyscall("update", {
        id: convexToJson(id),
        value: convexToJson(value as Value),
      });
      return Promise.resolve();
    },
    replace: (id, value) => {
      performSyscall("replace", {
        id: convexToJson(id),
        value: convexToJson(value),
      });
      return Promise.resolve();
    },
    delete: id => {
      performSyscall("remove", { id: convexToJson(id) });
      return Promise.resolve();
    },
  };
}
