import { AuthMec } from "~/prisma/client/enums";
import { OIDCManager } from "./oidc";
import { logger } from "~/server/internal/logging";

class AuthManager {
  private authProviders: {
    [AuthMec.Simple]: boolean;
    [AuthMec.OpenID]: OIDCManager | undefined;
  } = {
    [AuthMec.Simple]: false,
    [AuthMec.OpenID]: undefined,
  };

  private initFuncs: {
    [K in keyof typeof this.authProviders]: () => Promise<unknown>;
  } = {
    [AuthMec.OpenID]: OIDCManager.create,
    [AuthMec.Simple]: async () => {
      const disabled = process.env.DISABLE_SIMPLE_AUTH as string | undefined;
      return !disabled;
    },
  };

  async init() {
    for (const [key, init] of Object.entries(this.initFuncs)) {
      try {
        const object = await init();
        if (!object) break;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        (this.authProviders as any)[key] = object;
        logger.info(`enabled auth: ${key}`);
      } catch (e) {
        logger.warn(
          `failed to enable auth ${key}: ${(e as string).toString()}`,
        );
      }
    }

    // Add every other auth mechanism here, and fall back to simple if none of them are enabled
    if (!this.authProviders[AuthMec.OpenID]) {
      this.authProviders[AuthMec.Simple] = true;
    }

    logger.info("AuthManager initialized");
  }

  getAuthProviders() {
    return this.authProviders;
  }

  getEnabledAuthProviders() {
    const authManagers = Object.entries(this.authProviders)
      .filter((e) => !!e[1])
      .map((e) => e[0]);

    return authManagers;
  }
}

const authManager = new AuthManager();
export default authManager;

export * from "./passwordHash";
