import { contentType } from "jsr:@std/media-types";
import {HTML} from "./assemble_files.ts";

// Parse the port from the command-line arguments, defaulting to 8000
const port = parseInt(Deno.args[0] || "8000", 10);
const sockets: WebSocket[] = [];
const devinc = await fetch(import.meta.resolve("../src/dev.js")).then(r=>r.text());

let html: string;
try {
  html = Deno.readTextFileSync("./index.html");
} catch (_) {
  html = HTML;
}
html = html.replace("</head>", `<script type="module">${devinc}</script></head>`);

function extension(path: string): string {
  // Remove trailing slash if it exists
  const normalizedPath = path.endsWith("/") ? path.slice(0, -1) : path;
  // Get the last part of the path
  const lastPart = normalizedPath.split("/").pop() || "";
  // Check if the last part contains a "."
  return lastPart.split(".")[1] || "";
}

// Start the HTTP server using Deno.serve
Deno.serve({ port }, async (req: Request) => {
  const url = new URL(req.url);

  // Handle WebSocket connections
  if (url.pathname === "/ws") {
    const { socket, response } = Deno.upgradeWebSocket(req);
    sockets.push(socket);
    return response;
  }

  // Serve static files or the predefined HTML for non-file routes
  const path = new URL(req.url).pathname;
  const ext = extension(path);

  // Serve the predefined HTML for non-file routes
  if (!ext) {
    return new Response(html, {
      headers: { "Content-Type": "text/html" },
    });
  }

  try {
    const file = await Deno.open("." + path, { read: true });
    return new Response(file.readable, {
      headers: { "Content-Type": contentType(ext) || "application/javascript" },
    });
  } catch (err) {
    if (err instanceof Deno.errors.NotFound) {
      return new Response("File not found", { status: 404 });
    } else {
      return new Response("Internal server error", { status: 500 });
    }
  }
});

// Start watching for file changes
const watcher = Deno.watchFs(".");
for await (const event of watcher) {
  if (event.kind === "modify") {
    for (const ws of sockets) {
        if (ws.readyState === WebSocket.OPEN) {
          ws.send("reload");
          continue;
        }
      }
  }
}