import { TestPipeline } from "./pipeline.js";
import { Logger } from "../core/logger/core.js";
import { nodeLogDestination } from "../core/logger/node.js";
import { toRoutingStrategy } from "../i18n/utils.js";
import { validateConfig } from "../core/config/config.js";
import { ASTRO_CONFIG_DEFAULTS } from "../core/config/schema.js";
import { RenderContext } from "../core/render-context.js";
import { posix } from "node:path";
import { getParts, getPattern, validateSegment } from "../core/routing/manifest/create.js";
import { removeLeadingForwardSlash } from "../core/path.js";
function createContainerManifest(renderers, config, middleware) {
  let i18nManifest = void 0;
  if (config?.i18n) {
    i18nManifest = {
      fallback: config?.i18n.fallback,
      strategy: toRoutingStrategy(config?.i18n.routing, config?.i18n.domains),
      defaultLocale: config?.i18n.defaultLocale,
      locales: config?.i18n.locales,
      domainLookupTable: {}
    };
  }
  const defaultMiddleware = (_, next) => {
    return next();
  };
  return {
    rewritingEnabled: false,
    trailingSlash: config?.trailingSlash,
    buildFormat: config?.build.format,
    compressHTML: config?.compressHTML,
    assets: /* @__PURE__ */ new Set(),
    entryModules: {},
    routes: [],
    adapterName: "",
    clientDirectives: /* @__PURE__ */ new Map(),
    renderers,
    base: config?.base,
    componentMetadata: /* @__PURE__ */ new Map(),
    inlinedScripts: /* @__PURE__ */ new Map(),
    i18n: i18nManifest,
    checkOrigin: false,
    middleware: middleware ?? defaultMiddleware
  };
}
class unstable_AstroContainer {
  #pipeline;
  #config;
  constructor(streaming, renderers, config, resolve, manifest) {
    this.#config = config;
    this.#pipeline = TestPipeline.create({
      logger: new Logger({
        level: "info",
        dest: nodeLogDestination
      }),
      manifest: manifest ?? createContainerManifest(renderers, config),
      streaming,
      serverLike: true,
      renderers,
      resolve: async (specifier) => {
        if (resolve) {
          return resolve(specifier);
        } else {
          return this.containerResolve(specifier);
        }
      }
    });
  }
  async containerResolve(_specifier) {
    return "";
  }
  static async create(containerOptions = {}) {
    const {
      astroConfig = ASTRO_CONFIG_DEFAULTS,
      streaming = false,
      renderers = [],
      resolve,
      manifest
    } = containerOptions;
    const config = await validateConfig(astroConfig, process.cwd(), "container");
    return new unstable_AstroContainer(streaming, renderers, config, resolve, manifest);
  }
  insertRoute({
    path,
    componentInstance,
    params = [],
    type = "page"
  }) {
    const pathUrl = new URL(path, "https://example.com");
    const routeData = this.createRoute(pathUrl, params, type);
    this.#pipeline.manifest.routes.push({
      routeData,
      file: "",
      links: [],
      styles: [],
      scripts: []
    });
    this.#pipeline.insertRoute(routeData, componentInstance);
    return routeData;
  }
  async renderToString(component, options = {}) {
    const response = await this.renderToResponse(component, options);
    return await response.text();
  }
  async renderToResponse(component, options = {}) {
    const { routeType = "page", slots } = options;
    const request = options?.request ?? new Request("https://example.com/");
    const params = options?.params ?? [];
    const url = new URL(request.url);
    const routeData = this.insertRoute({
      path: request.url,
      componentInstance: component,
      params,
      type: routeType
    });
    const renderContext = RenderContext.create({
      pipeline: this.#pipeline,
      routeData,
      status: options?.status ?? 200,
      middleware: this.#pipeline.middleware,
      request,
      pathname: url.pathname,
      locals: options?.locals ?? {}
    });
    return renderContext.render(component, slots);
  }
  createRoute(url, params, type) {
    const segments = removeLeadingForwardSlash(url.pathname).split(posix.sep).filter(Boolean).map((s) => {
      validateSegment(s);
      return getParts(s, url.pathname);
    });
    return {
      component: "",
      generate(_data) {
        return "";
      },
      params,
      pattern: getPattern(segments, this.#config, this.#config.trailingSlash),
      prerender: false,
      segments,
      type,
      route: url.pathname,
      fallbackRoutes: [],
      isIndex: false
    };
  }
}
export {
  unstable_AstroContainer
};
