import { Command, Flags } from "@oclif/core";
import { startBrowserBridgeServer } from "@elench/testkit-bridge";
import { loadConfigContext, resolveProductDir } from "../../../config/index.mjs";
import { discoverTests } from "../../../discovery/index.mjs";
import { loadCurrentRunArtifact } from "../../viewer.mjs";

export default class BrowserServeCommand extends Command {
  static summary = "Serve the local browser bridge for the current testkit product";

  static enableJsonFlag = true;

  static flags = {
    dir: Flags.string({
      description: "Product directory",
    }),
    host: Flags.string({
      description: "Host to bind the browser bridge server",
      default: "127.0.0.1",
    }),
    port: Flags.integer({
      description: "Port to bind the browser bridge server",
      default: 3847,
    }),
  };

  async run() {
    const { flags } = await this.parse(BrowserServeCommand);
    const productDir = resolveProductDir(process.cwd(), flags.dir);

    const adapter = {
      loadProductContext: async () => {
        const [configContext, discovery] = await Promise.all([
          loadConfigContext({
            dir: productDir,
            discoveryOptions: { strict: false },
          }),
          discoverTests({
            dir: productDir,
            diagnostics: "report",
          }),
        ]);

        return {
          product: {
            name: discovery.product.name,
            directory: discovery.product.directory,
          },
          services: configContext.configs
            .map((config) => {
              const baseUrl = config.testkit.local?.baseUrl || null;
              const browserOrigins = config.testkit.browser?.origins || [];
              if (!baseUrl && browserOrigins.length === 0) return null;
              const serviceEntries = [];
              if (baseUrl && !baseUrl.includes("{port}")) {
                try {
                  const parsed = new URL(baseUrl);
                  serviceEntries.push({
                    name: config.name,
                    baseUrl,
                    origin: parsed.origin,
                  });
                } catch {
                  // Ignore invalid local.baseUrl templates here; explicit browser origins still work.
                }
              }
              for (const origin of browserOrigins) {
                serviceEntries.push({
                  name: config.name,
                  baseUrl: origin,
                  origin,
                });
              }
              return serviceEntries;
            })
            .flat()
            .filter(Boolean),
          discovery,
          runArtifact: loadRunArtifactIfPresent(productDir),
        };
      },
    };

    const serverRef = await startBrowserBridgeServer(adapter, {
      host: flags.host,
      port: flags.port,
    });

    const payload = {
      ok: true,
      productDir,
      host: serverRef.host,
      port: serverRef.port,
      url: serverRef.url,
    };

    if (!this.jsonEnabled()) {
      this.log(`testkit browser bridge serving ${productDir}`);
      this.log(`Listening on ${serverRef.url}`);
    }

    await new Promise(() => {});
    return payload;
  }
}

function loadRunArtifactIfPresent(productDir) {
  try {
    return loadCurrentRunArtifact(productDir);
  } catch {
    return null;
  }
}
