import { Model } from "@localsecurity/types";
import { ModelName, NameID, NameIdString, isModelName } from "./name-id";

const ErrorResponse = (e: any) => Response.json({ error: e }, { status: 500 });

/**
 * Handle a request with a Model Name in the body
 */
async function handleName(request: Request) {
  const __typename = await request.text();

  const execute = () => {
    if (isModelName(__typename)) {
      const nameId = new NameID(__typename).value;
      const createdAt = NameID.parse(nameId).timestamp.toISOString();
      return Response.json({ nameId, createdAt, __typename });
    } else {
      return ErrorResponse(`Not a valid Model Name ('${__typename}')`);
    }
  };

  try {
    return execute();
  } catch (e: any) {
    return ErrorResponse(e);
  }
}

/**
 * Handle a request with a Model Object in the body
 */
async function handleObject(request: Request) {
  const object: Model[ModelName] = await request.json();

  const __typename = object["__typename"];

  const execute = () => {
    if (isModelName(__typename)) {
      const nameId: NameIdString = new NameID(object).value;
      return Response.json({ nameId, ...object });
    } else {
      return ErrorResponse(`Not a valid Model Name ('${__typename}')`);
    }
  };

  try {
    return execute();
  } catch (e: any) {
    return ErrorResponse(e);
  }
}

/**
 * Worker entrypoint
 */
export default {
  async fetch(request: Request, env: any, ctx: any) {
    const contentType = request.headers.get("content-type") ?? "";

    const execute = () => {
      if (contentType.includes("json")) return handleObject(request);
      else return handleName(request);
    };

    try {
      return execute();
    } catch (e: any) {
      return ErrorResponse(e);
    }
  },
};
