// config/env.ts
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved

import path, { dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { loadGadgetCodeConfig, resolvePath } from "@gadget/config";
import type PackageJson from "../../package.json";
import { GadgetLog, GadgetLogFile } from "@gadget/api";

const __dirname = dirname(fileURLToPath(import.meta.url));

// INSTALL_DIR: where the package is installed (for loading assets, etc.)
export const INSTALL_DIR = path.resolve(__dirname, "..", "..");

// Load YAML configuration
const yamlConfig = loadGadgetCodeConfig();

// Validate required fields
if (!yamlConfig.auth?.jwtSecret) {
  throw new Error(
    "Configuration error: auth.jwtSecret is required in gadget-code.yaml\n" +
      "See documentation: ./docs/configuration.md",
  );
}
if (!yamlConfig.auth?.passwordSalt) {
  throw new Error(
    "Configuration error: auth.passwordSalt is required in gadget-code.yaml\n" +
      "See documentation: ./docs/configuration.md",
  );
}
if (!yamlConfig.session?.secret) {
  throw new Error(
    "Configuration error: session.secret is required in gadget-code.yaml\n" +
      "See documentation: ./docs/configuration.md",
  );
}

async function readJsonFile<T>(filePath: string): Promise<T> {
  const fs = await import("node:fs");
  const file = await fs.promises.readFile(filePath);
  return JSON.parse(file.toString("utf-8")) as T;
}

export interface ISiteDefinition {
  company: string;
  companyShort: string;
  name: string;
  shortName: string;
  tagline: string;
  slogan: string;
  description: string;
  domain: string;
  domainKey: string;
  host: string;
}

export default {
  NODE_ENV: process.env.NODE_ENV,
  timezone: yamlConfig.timezone || "America/New_York",
  installDir: INSTALL_DIR,
  pkg: await readJsonFile<typeof PackageJson>(
    path.join(INSTALL_DIR, "package.json"),
  ),
  site: {
    company: yamlConfig.site?.company || "Robert Colbert",
    companyShort: yamlConfig.site?.companyShort || "Colbert",
    name: yamlConfig.site?.name || "Gadget Code",
    shortName: yamlConfig.site?.shortName || "Gadget Code",
    slogan:
      yamlConfig.site?.slogan || "Self-hosted Agentic Engineering Platform",
    description:
      yamlConfig.site?.description ||
      "Gadget Code - A self-hosted Agentic Engineering Platform (AEP).",
    domain: yamlConfig.site?.domain || "code-dev.g4dge7.com",
    domainKey: yamlConfig.site?.domainKey || "code-dev.g4dge7.com",
    host: yamlConfig.site?.host || "code-dev.g4dge7.com",
  },
  ai: {
    ollama: {
      apiUrl: process.env.DTP_OLLAMA_API_URL || "http://localhost:11434",
      apiKey: process.env.DTP_OLLAMA_API_KEY || "",
    },
  },
  auth: {
    jwtSecret: yamlConfig.auth.jwtSecret,
  },
  session: {
    secret: yamlConfig.session.secret,
    trustProxy:
      process.env.NODE_ENV === "production" ||
      yamlConfig.session?.trustProxy === true,
    cookie: {
      secure: yamlConfig.session?.cookie?.secure === true,
      sameSite: yamlConfig.session?.cookie?.sameSite || false,
    },
  },
  google: {
    cse: {
      apiKey: yamlConfig.google.cse.apiKey,
      engineId: yamlConfig.google.cse.engineId,
    },
  },
  mongodb: {
    host: yamlConfig.mongodb?.host || "localhost",
    database: yamlConfig.mongodb?.database || "",
  },
  redis: {
    host: yamlConfig.redis?.host || "localhost",
    port: yamlConfig.redis?.port || 6379,
    password: yamlConfig.redis?.password,
    keyPrefix: yamlConfig.redis?.keyPrefix || "dtp",
    lazyConnect: yamlConfig.redis?.lazyConnect === true,
  },
  minio: {
    endpoint: yamlConfig.minio?.endpoint || "localhost",
    port: yamlConfig.minio?.port || 9080,
    useSsl: yamlConfig.minio?.useSsl === true,
    accessKey: yamlConfig.minio?.accessKey,
    secretKey: yamlConfig.minio?.secretKey,
    buckets: {
      uploads: yamlConfig.minio?.buckets?.uploads || "dtp-uploads",
      images: yamlConfig.minio?.buckets?.images || "dtp-images",
      videos: yamlConfig.minio?.buckets?.videos || "dtp-videos",
      audios: yamlConfig.minio?.buckets?.audios || "dtp-audios",
    },
  },
  user: {
    passwordSalt: yamlConfig.auth.passwordSalt,
  },
  https: {
    enabled: yamlConfig.https?.enabled === true,
    address: yamlConfig.https?.address || "127.0.0.1",
    port: yamlConfig.https?.port || 3443,
    backlog: yamlConfig.https?.backlog || 16,
    keyFile: yamlConfig.https?.keyFile,
    crtFile: yamlConfig.https?.crtFile,
    uploadPath: yamlConfig.https?.uploadPath || "/tmp",
  },
  socket: {
    maxHttpBufferSize: yamlConfig.socket?.maxHttpBufferSize || 1048576,
  },
  frontend: {
    port: 5173,
  },
  email: {
    enabled: yamlConfig.email?.enabled === true,
    smtp: {
      host: yamlConfig.email?.smtp?.host || "localhost",
      port: yamlConfig.email?.smtp?.port || 465,
      secure: yamlConfig.email?.smtp?.secure === true,
      from:
        yamlConfig.email?.smtp?.from ||
        "Digital Telepresence Support <support@digitaltelepresence.com>",
      user: yamlConfig.email?.smtp?.user,
      password: yamlConfig.email?.smtp?.password,
      pool: {
        enabled: yamlConfig.email?.smtp?.pool?.enabled === true,
        maxConnections: yamlConfig.email?.smtp?.pool?.maxConnections || 5,
        maxMessages: yamlConfig.email?.smtp?.pool?.maxMessages || 100,
      },
    },
    contact: {
      to:
        yamlConfig.email?.contact?.to ||
        "DTP Support <support@digitaltelepresence.com>",
    },
  },
  log: {
    https: {
      enabled: yamlConfig.logging?.https?.enabled === true || false,
      name: yamlConfig.logging?.https?.name || "gadget-code-https.log",
      path: yamlConfig.logging?.https?.path
        ? resolvePath(yamlConfig.logging.https.path)
        : "/var/log/dtp",
      format: yamlConfig.logging?.https?.format || "combined",
    },
    console: {
      enabled: yamlConfig.logging?.console?.enabled === true,
    },
    file: {
      enabled: yamlConfig.logging?.file?.enabled === true,
      path: yamlConfig.logging?.file?.path
        ? resolvePath(yamlConfig.logging.file.path)
        : path.join(INSTALL_DIR, "logs"),
      name: yamlConfig.logging?.file?.name || "gadget-code",
      maxWritesPerFile: yamlConfig.logging?.file?.maxWritesPerFile || 10000,
      maxFiles: yamlConfig.logging?.file?.maxFiles || 10,
    },
    levels: {
      debug: yamlConfig.logging?.levels?.debug === true,
      info: yamlConfig.logging?.levels?.info === true,
      warn: yamlConfig.logging?.levels?.warn === true,
    },
  },
};

// Configure GadgetLog for this package
GadgetLog.consoleEnabled = yamlConfig.logging?.console?.enabled === true;
if (yamlConfig.logging?.file?.enabled === true) {
  const logFileOptions = {
    basePath: yamlConfig.logging.file.path
      ? resolvePath(yamlConfig.logging.file.path)
      : path.join(INSTALL_DIR, "logs"),
    name: yamlConfig.logging.file.name || "gadget-code",
    maxWritesPerFile: yamlConfig.logging.file.maxWritesPerFile || 10000,
    maxFiles: yamlConfig.logging.file.maxFiles || 10,
  };
  const defaultLogFile = new GadgetLogFile(logFileOptions);
  defaultLogFile.open();
  GadgetLog.defaultFile = defaultLogFile;
}
