import { defineAsyncComponent } from "vue";
const schemaModules = import.meta.glob(
  "../*/*/schema.{ts,js}",
  { eager: true, exhaustive: true }
);
const runtimeModules = import.meta.glob(
  "../*/*/runtime.{ts,js}",
  { eager: true, exhaustive: true }
);
const configModuleLoaders = import.meta.glob(
  "../*/*/config.vue",
  { exhaustive: true }
);
const configModules = Object.fromEntries(
  Object.entries(configModuleLoaders).map(([path, loader]) => [
    path,
    defineAsyncComponent(loader)
  ])
);
const PATH_RE = /\/([^/]+)\/([^/]+)\/schema\.(?:ts|js)$/;
function findSibling(map, date, type, file) {
  const candidates = file.endsWith(".ts") ? [file, `${file.slice(0, -3)}.js`] : [file];
  for (const candidate of candidates) {
    const suffix = `/${date}/${type}/${candidate}`;
    for (const [key, value] of Object.entries(map)) {
      if (key.endsWith(suffix)) return value;
    }
  }
  throw new Error(`[shwfed-operations] missing ${file} for ${type}@${date}`);
}
let cached = null;
function compute() {
  if (cached) return cached;
  const entries = [];
  for (const [path, mod] of Object.entries(schemaModules)) {
    const match = PATH_RE.exec(path);
    if (!match) throw new Error(`[shwfed-operations] unrecognized schema path: ${path}`);
    const date = match[1];
    const type = match[2];
    if (mod.type !== type) {
      throw new Error(`[shwfed-operations] type "${mod.type}" does not match folder "${type}"`);
    }
    if (mod.compatibilityDate !== date) {
      throw new Error(`[shwfed-operations] compatibilityDate "${mod.compatibilityDate}" does not match folder "${date}"`);
    }
    const runtime = findSibling(runtimeModules, date, type, "runtime.ts");
    entries.push({
      type: mod.type,
      compatibilityDate: mod.compatibilityDate,
      metadata: mod.metadata,
      schema: mod.schema,
      defaults: mod.defaults,
      config: findSibling(configModules, date, type, "config.vue"),
      handler: runtime.handler
    });
  }
  cached = entries;
  return cached;
}
export const OPERATIONS = new Proxy([], {
  get(_t, prop, recv) {
    return Reflect.get(compute(), prop, recv);
  }
});
export function findOperation(type, compatibilityDate) {
  return compute().find((o) => o.type === type && o.compatibilityDate === compatibilityDate);
}
export function operationHandlers(exposed, ctx) {
  const handlers = {};
  for (const { type, compatibilityDate } of exposed) {
    const entry = findOperation(type, compatibilityDate);
    if (!entry) continue;
    handlers[type] = (params, cel, step) => entry.handler(params, { ...ctx, ...cel && { cel }, ...step && { step } });
  }
  return handlers;
}
