// src/models/api-client.ts
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved

import { Schema, model } from "mongoose";

import { GadgetId, IUser } from "@gadget/api";
import { nanoid } from "nanoid";

export enum ApiClientStatus {
  Active = "active",
  Inactive = "inactive",
  Archived = "archived",
}

/**
 * An API client is either machine-to-machine (no User), or a User access client
 * that can call services on the User's scoped behalf. When a request presents
 * an ApiClient token, we populate req.user with that User account. The
 * remainder of the request proceeds with that User's authentication and
 * authorization.
 *
 * An example of non-User communication is a gadget-drone performing an initial
 * Platform registration. It presents the User's credentials to authenticate the
 * request, and we verify the API key to authenticate that client before
 * trusting the credentials presented.
 */
export interface IApiClient {
  _id: GadgetId;
  createdAt: Date;
  updatedAt: Date;
  status: ApiClientStatus;
  name: string;
  description?: string;
  secret: string;
  user?: IUser | GadgetId;
}
const ApiClientSchema = new Schema<IApiClient>({
  _id: { type: String, default: () => nanoid() },
  createdAt: { type: Date, required: true },
  updatedAt: { type: Date, required: true },
  status: {
    type: String,
    enum: ApiClientStatus,
    default: ApiClientStatus.Active,
    required: true,
    index: 1,
  },
  name: { type: String, required: true },
  description: { type: String },
  secret: { type: String, required: true },
  user: { type: String, ref: "User", index: 1 },
});

export const ApiClient = model<IApiClient>("ApiClient", ApiClientSchema);
export default ApiClient;

(async () => {
  await ApiClient.syncIndexes();
})();
