// h dev seed-traefik
// deno run -A ./.scripts/seed-traefik.ts

import * as yaml from "jsr:@std/yaml";
import * as path from "jsr:@std/path";

import { listComposeFiles, paths } from "../routines/paths.js";
import { log } from "../routines/utils.js";

async function main() {
  // We want to find all "root" service files that look like:
  // compose.ollama.yml
  // compose.traefik.yml
  // etc.
  const sourceFiles = await listComposeFiles().then((files) =>
    files.filter((name) => name.split(".").length === 3)
  );
  log.debug(sourceFiles.join(" "));

  // All services that expose a port will have a traefik file as well
  await Promise.all(
    sourceFiles.map(async (file) => {
      const filePath = path.join(paths.services, file);
      return {
        name: file,
        contents: yaml.parse(await Deno.readTextFile(filePath))
      }
    })
  )
    .then((files) => {
      const targetFiles = files.filter((file) => {
        const services = file.contents.services;
        return Object.keys(services).some((key) => {
          const service = services[key];
          return service.ports && service.ports.length > 0;
        });
      })

      return targetFiles;
    })
    .then((files) => {
      return files.map((file) => {
        log.debug('Seeding for', file.name)
        const outName = file.name.replace("compose.", "compose.x.traefik.");
        const serviceName = file.name.split(".")[1];
        const ports = file.contents.services[serviceName].ports;

        if (!ports || ports.length === 0) {
          log.debug(`Skipping ${serviceName} as it has no ports`);
          return;
        }

        if (serviceName === 'traefik') {
          log.debug(`Skipping ${serviceName} as it is traefik`);
          return;
        }

        const port = ports[0].split(":")[1];
        const content =
          `
# This file is generated by seed-traefik.ts script,
# any updates will be overwritten.
services:
  ${serviceName}:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.${serviceName}.rule=Host(\`${serviceName}.\${HARBOR_TRAEFIK_DOMAIN}\`)"
      - "traefik.http.services.${serviceName}.loadbalancer.server.port=${port}"
      - "traefik.http.routers.${serviceName}.entrypoints=websecure"
      - "traefik.http.routers.${serviceName}.tls=true"
      - "traefik.http.routers.${serviceName}.service=${serviceName}"

    networks:
      - traefik-public
`.trim() + "\n";

        const outPath = path.join(paths.services, outName);
        log.debug(`Writing ${outPath}...`);
        Deno.writeTextFile(outPath, content);
      });
    });
}

main().catch(console.error);
