import swaggerJSDoc from "@deadendjs/swagger-jsdoc";
import path from "path";
import { fileURLToPath } from "url";
import { promises as fs } from "fs";
import { systemLogger } from "./logger.js";

type SwaggerJSDocOptions = Parameters<typeof swaggerJSDoc>[0];

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

const swaggerOptions: SwaggerJSDocOptions = {
  definition: {
    openapi: "3.0.3",
    info: {
      title: "Termix API",
      version: "0.0.0",
      description: "Termix Backend API Reference",
    },
    servers: [
      {
        url: "http://localhost:30001",
        description: "Main database and authentication server",
      },
      {
        url: "http://localhost:30003",
        description: "SSH tunnel management server",
      },
      {
        url: "http://localhost:30004",
        description: "SSH file manager server",
      },
      {
        url: "http://localhost:30005",
        description: "Server statistics and monitoring server",
      },
      {
        url: "http://localhost:30006",
        description: "Dashboard server",
      },
      {
        url: "http://localhost:30007",
        description: "Docker management server",
      },
      {
        url: "http://localhost:30011",
        description: "Serial connection server",
      },
    ],
    components: {
      securitySchemes: {
        bearerAuth: {
          type: "http",
          scheme: "bearer",
          bearerFormat: "JWT",
        },
      },
      schemas: {
        Error: {
          type: "object",
          properties: {
            error: { type: "string" },
            details: { type: "string" },
          },
        },
      },
    },
    security: [
      {
        bearerAuth: [],
      },
    ],
    tags: [
      {
        name: "AI",
        description: "AI assistant providers, conversations and proposals",
      },
      {
        name: "Alerts",
        description: "System alerts and notifications management",
      },
      {
        name: "Credentials",
        description: "SSH credential management",
      },
      {
        name: "Network Topology",
        description: "Network topology visualization and management",
      },
      {
        name: "RBAC",
        description: "Role-based access control for host sharing",
      },
      {
        name: "Snippets",
        description: "Command snippet management",
      },
      {
        name: "Terminal",
        description: "Terminal command history",
      },
      {
        name: "Users",
        description: "User management and authentication",
      },
      {
        name: "Dashboard",
        description: "Dashboard statistics and activity",
      },
      {
        name: "Docker",
        description: "Docker container management",
      },
      {
        name: "SSH Tunnels",
        description: "SSH tunnel connection management",
      },
      {
        name: "Host Metrics",
        description: "Host status monitoring, metrics collection, and managers",
      },
      {
        name: "File Manager",
        description: "SSH file management operations",
      },
      {
        name: "SSH",
        description: "SSH host management and configuration",
      },
      {
        name: "Host Enrollment",
        description: "Host enrollment and onboarding",
      },
      {
        name: "Fleets",
        description: "Fleet grouping, membership, and inventory",
      },
      {
        name: "Workspaces",
        description: "Saved tab and split layouts",
      },
      {
        name: "Open Tabs",
        description: "Per-user open tab state",
      },
      {
        name: "Automations",
        description: "Scheduled and triggered automations",
      },
      {
        name: "Guacamole",
        description: "RDP, VNC, and Telnet remote desktop sessions",
      },
      {
        name: "Proxmox",
        description: "Proxmox host integration",
      },
      {
        name: "Proxmox Stats",
        description: "Proxmox node and VM statistics",
      },
      {
        name: "Session Sharing",
        description: "Live terminal session collaboration",
      },
      {
        name: "Session Logs",
        description: "Session recording and playback",
      },
      {
        name: "Homepage",
        description: "Homepage service links and layout",
      },
      {
        name: "Audit",
        description: "Audit log querying and export",
      },
      {
        name: "API Keys",
        description: "API key management",
      },
      {
        name: "SSO",
        description: "Single sign-on provider configuration",
      },
      {
        name: "WebAuthn",
        description: "Passkey registration and authentication",
      },
      {
        name: "Vault",
        description: "HashiCorp Vault SSH signing profiles",
      },
      {
        name: "Termix ID",
        description: "Built-in SSH certificate authority",
      },
      {
        name: "Tailscale",
        description: "Tailscale network integration",
      },
      {
        name: "Sync",
        description: "Remote sync between desktop and server",
      },
      {
        name: "Tunnel Presets",
        description: "Saved tunnel configurations",
      },
      {
        name: "User Preferences",
        description: "Per-user application preferences",
      },
      {
        name: "UI Preferences",
        description: "Interface layout and display preferences",
      },
      {
        name: "Host Sidebar",
        description: "Host sidebar display preferences",
      },
      {
        name: "Credential Sidebar",
        description: "Credential sidebar display preferences",
      },
    ],
  },
  apis: [
    path
      .join(__dirname, "..", "database", "routes", "*.js")
      .replace(/\\/g, "/"),
    path.join(__dirname, "..", "ai", "*.js").replace(/\\/g, "/"),
    path.join(__dirname, "..", "services", "*.js").replace(/\\/g, "/"),
    path.join(__dirname, "..", "hosts", "*.js").replace(/\\/g, "/"),
    path.join(__dirname, "..", "hosts", "**", "*.js").replace(/\\/g, "/"),
  ],
};

async function generateOpenAPISpec() {
  try {
    systemLogger.info("Generating OpenAPI specification", {
      operation: "openapi_generate_start",
    });

    const swaggerSpec = await swaggerJSDoc(swaggerOptions);

    const outputPath = path.join(
      __dirname,
      "..",
      "..",
      "..",
      "..",
      "openapi.json",
    );

    await fs.writeFile(
      outputPath,
      JSON.stringify(swaggerSpec, null, 2),
      "utf-8",
    );

    systemLogger.success("OpenAPI specification generated", {
      operation: "openapi_generate_success",
    });
  } catch (error) {
    systemLogger.error("Failed to generate OpenAPI specification", error, {
      operation: "openapi_generation",
    });
    process.exit(1);
  }
}

generateOpenAPISpec();

export { swaggerOptions, generateOpenAPISpec };
