import '../../server/web/globals';
import { adapter } from '../../server/web/adapter';
import { IncrementalCache } from '../../server/lib/incremental-cache';
import { initializeCacheHandlers } from '../../server/use-cache/handlers';
import Document from 'VAR_MODULE_DOCUMENT';
import * as appMod from 'VAR_MODULE_APP';
import * as userlandPage from 'VAR_USERLAND';
import * as userlandErrorPage from 'VAR_MODULE_GLOBAL_ERROR';
// OPTIONAL_IMPORT:* as userland500Page
// OPTIONAL_IMPORT:incrementalCacheHandler
// TODO: re-enable this once we've refactored to use implicit matches
// const renderToHTML = undefined
import RouteModule from '../../server/route-modules/pages/module';
import { WebNextRequest, WebNextResponse } from '../../server/base-http/web';
import { getTracer, SpanKind } from '../../server/lib/trace/tracer';
import { BaseServerSpan } from '../../server/lib/trace/constants';
// INJECT:nextConfig
// INJECT:pageRouteModuleOptions
// INJECT:errorRouteModuleOptions
// INJECT:user500RouteModuleOptions
// Initialize the cache handlers interface.
initializeCacheHandlers();
globalThis.nextConfig = nextConfig;
const pageMod = {
    ...userlandPage,
    routeModule: new RouteModule({
        ...pageRouteModuleOptions,
        components: {
            App: appMod.default,
            Document
        },
        userland: userlandPage
    })
};
const errorMod = {
    ...userlandErrorPage,
    routeModule: new RouteModule({
        ...errorRouteModuleOptions,
        components: {
            App: appMod.default,
            Document
        },
        userland: userlandErrorPage
    })
};
// FIXME: this needs to be made compatible with the template
const error500Mod = userland500Page ? {
    ...userland500Page,
    routeModule: new RouteModule({
        ...user500RouteModuleOptions,
        components: {
            App: appMod.default,
            Document
        },
        userland: userland500Page
    })
} : null;
export const ComponentMod = pageMod;
async function requestHandler(req, _event) {
    var _nextConfig_experimental_amp, _nextConfig_i18n;
    let srcPage = 'VAR_PAGE';
    const relativeUrl = `${req.nextUrl.pathname}${req.nextUrl.search}`;
    const baseReq = new WebNextRequest(req);
    const pageRouteModule = pageMod.routeModule;
    const prepareResult = await pageRouteModule.prepare(baseReq, null, {
        srcPage,
        multiZoneDraftMode: false
    });
    if (!prepareResult) {
        return new Response('Bad Request', {
            status: 400
        });
    }
    const { query, params, buildId, isNextDataRequest, buildManifest, prerenderManifest, reactLoadableManifest, clientReferenceManifest, subresourceIntegrityManifest, dynamicCssManifest } = prepareResult;
    const renderContext = {
        page: srcPage,
        query,
        params,
        sharedContext: {
            buildId,
            deploymentId: process.env.NEXT_DEPLOYMENT_ID,
            customServer: undefined
        },
        renderContext: {
            isFallback: false,
            isDraftMode: false,
            developmentNotFoundSourcePage: undefined
        },
        renderOpts: {
            params,
            page: srcPage,
            supportsDynamicResponse: true,
            Component: pageMod.Component,
            ComponentMod: pageMod,
            pageConfig: pageMod.pageConfig,
            routeModule: pageMod.routeModule,
            strictNextHead: nextConfig.experimental.strictNextHead ?? true,
            canonicalBase: nextConfig.amp.canonicalBase || '',
            previewProps: prerenderManifest.preview,
            ampOptimizerConfig: (_nextConfig_experimental_amp = nextConfig.experimental.amp) == null ? void 0 : _nextConfig_experimental_amp.optimizer,
            basePath: nextConfig.basePath,
            assetPrefix: nextConfig.assetPrefix,
            images: nextConfig.images,
            optimizeCss: nextConfig.experimental.optimizeCss,
            nextConfigOutput: nextConfig.output,
            nextScriptWorkers: nextConfig.experimental.nextScriptWorkers,
            disableOptimizedLoading: nextConfig.experimental.disableOptimizedLoading,
            domainLocales: (_nextConfig_i18n = nextConfig.i18n) == null ? void 0 : _nextConfig_i18n.domains,
            distDir: '',
            crossOrigin: nextConfig.crossOrigin ? nextConfig.crossOrigin : undefined,
            largePageDataBytes: nextConfig.experimental.largePageDataBytes,
            // Only the `publicRuntimeConfig` key is exposed to the client side
            // It'll be rendered as part of __NEXT_DATA__ on the client side
            runtimeConfig: Object.keys(nextConfig.publicRuntimeConfig).length > 0 ? nextConfig.publicRuntimeConfig : undefined,
            isExperimentalCompile: nextConfig.experimental.isExperimentalCompile,
            // `htmlLimitedBots` is passed to server as serialized config in string format
            experimental: {
                clientTraceMetadata: nextConfig.experimental.clientTraceMetadata
            },
            buildManifest,
            subresourceIntegrityManifest,
            reactLoadableManifest,
            clientReferenceManifest,
            dynamicCssManifest
        }
    };
    let finalStatus = 200;
    const renderResultToResponse = (result)=>{
        // Handle null responses
        if (result.isNull) {
            finalStatus = 500;
            return new Response(null, {
                status: 500
            });
        }
        // Extract metadata
        const { metadata } = result;
        finalStatus = metadata.statusCode || 200;
        const headers = new Headers();
        // Set content type
        const contentType = result.contentType || 'text/html; charset=utf-8';
        headers.set('Content-Type', contentType);
        // Add metadata headers
        if (metadata.headers) {
            for (const [key, value] of Object.entries(metadata.headers)){
                if (value !== undefined) {
                    if (Array.isArray(value)) {
                        // Handle multiple header values
                        for (const v of value){
                            headers.append(key, String(v));
                        }
                    } else {
                        headers.set(key, String(value));
                    }
                }
            }
        }
        // Handle static response
        if (!result.isDynamic) {
            const body = result.toUnchunkedString();
            headers.set('Content-Length', String(new TextEncoder().encode(body).length));
            return new Response(body, {
                status: finalStatus,
                headers
            });
        }
        // Handle dynamic/streaming response
        // For edge runtime, we need to create a readable stream that pipes from the result
        const { readable, writable } = new TransformStream();
        // Start piping the result to the writable stream
        // This is done asynchronously to avoid blocking the response creation
        result.pipeTo(writable).catch((err)=>{
            console.error('Error piping RenderResult to response:', err);
        });
        return new Response(readable, {
            status: finalStatus,
            headers
        });
    };
    const invokeRender = async (span)=>{
        try {
            const result = await pageRouteModule.render(// @ts-expect-error we don't type this for edge
            baseReq, new WebNextResponse(undefined), {
                ...renderContext,
                renderOpts: {
                    ...renderContext.renderOpts,
                    getServerSideProps: pageMod.getServerSideProps,
                    Component: pageMod.default || pageMod,
                    ComponentMod: pageMod,
                    pageConfig: pageMod.config,
                    isNextDataRequest
                }
            }).finally(()=>{
                if (!span) return;
                span.setAttributes({
                    'http.status_code': finalStatus,
                    'next.rsc': false
                });
                const rootSpanAttributes = tracer.getRootSpanAttributes();
                // We were unable to get attributes, probably OTEL is not enabled
                if (!rootSpanAttributes) {
                    return;
                }
                if (rootSpanAttributes.get('next.span_type') !== BaseServerSpan.handleRequest) {
                    console.warn(`Unexpected root span type '${rootSpanAttributes.get('next.span_type')}'. Please report this Next.js issue https://github.com/vercel/next.js`);
                    return;
                }
                const route = rootSpanAttributes.get('next.route');
                if (route) {
                    const name = `${req.method} ${route}`;
                    span.setAttributes({
                        'next.route': route,
                        'http.route': route,
                        'next.span_name': name
                    });
                    span.updateName(name);
                } else {
                    span.updateName(`${req.method} ${relativeUrl}`);
                }
            });
            return renderResultToResponse(result);
        } catch (err) {
            const errModule = error500Mod || errorMod;
            const errRouteModule = errModule.routeModule;
            if (errRouteModule.isDev) {
                throw err;
            }
            await errRouteModule.onRequestError(baseReq, err, {
                routerKind: 'Pages Router',
                routePath: srcPage,
                routeType: 'render',
                revalidateReason: undefined
            });
            const errResult = await errRouteModule.render(// @ts-expect-error we don't type this for edge
            baseReq, new WebNextResponse(undefined), {
                ...renderContext,
                page: error500Mod ? '/500' : '/_error',
                renderOpts: {
                    ...renderContext.renderOpts,
                    getServerSideProps: errModule.getServerSideProps,
                    Component: errModule.default || errModule,
                    ComponentMod: errModule,
                    pageConfig: errModule.config
                }
            });
            return renderResultToResponse(errResult);
        }
    };
    const tracer = getTracer();
    // TODO: activeSpan code path is for when wrapped by
    // next-server can be removed when this is no longer used
    return tracer.withPropagatedContext(req.headers, ()=>tracer.trace(BaseServerSpan.handleRequest, {
            spanName: `${req.method} ${relativeUrl}`,
            kind: SpanKind.SERVER,
            attributes: {
                'http.method': req.method,
                'http.target': relativeUrl,
                'http.route': srcPage
            }
        }, invokeRender));
}
export default function nHandler(opts) {
    return adapter({
        ...opts,
        IncrementalCache,
        handler: requestHandler,
        incrementalCacheHandler,
        bypassNextUrl: true
    });
}

//# sourceMappingURL=edge-ssr.js.map