"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResourceService = void 0;
const resource_1 = require("./resource");
const console_1 = require("../lib/console");
const build_1 = require("../build");
class ResourceService {
    constructor(manifest, prerenderManifest, routesManifest) {
        this.manifest = manifest;
        this.prerenderManifest = prerenderManifest;
        this.routesManifest = routesManifest;
    }
    get(event) {
        const resource = this.generateBasicResource(event);
        resource.routes = {
            fallback: this.findFallbackRoute(resource),
            prerender: this.findPrerenderRoute(resource),
            public: this.findPublicRoute(resource),
            static: this.findStaticRoute(resource),
            page: this.findPageRoute(resource)
        };
        return resource;
    }
    generateBasicResource(event) {
        const request = event.Records[0].cf.request;
        const uri = request.uri.replace(this.getBasePath(), "");
        if (uri.endsWith("/index.html")) {
            console_1.debug(`Rendered with Resource For Index Page`);
            return new resource_1.ResourceForIndexPage(uri, this.getBasePath(), this.getBuildId());
        }
        console_1.debug(`Rendered with Basic Resource`);
        return new resource_1.Resource(uri, this.getBasePath(), this.getBuildId());
    }
    getBasePath() {
        return this.routesManifest.basePath || "";
    }
    getBuildId() {
        return build_1.DEFAULT_BUILD_ID;
    }
    findStaticRoute(resource) {
        return this.manifest.pages.html.nonDynamic[resource.getNormalUri()];
    }
    findPublicRoute(resource) {
        return this.manifest.publicFiles[resource.getNormalUri()];
    }
    findPrerenderRoute(resource) {
        return this.prerenderManifest.routes[resource.getNormalUri()];
    }
    findPageRoute(resource) {
        const uri = resource.getCanonicalUri();
        const { pages: { ssr, html } } = this.manifest;
        const allDynamicRoutes = Object.assign(Object.assign({}, ssr.dynamic), html.dynamic);
        if (ssr.nonDynamic[uri]) {
            return ssr.nonDynamic[uri];
        }
        if (html.nonDynamic[uri]) {
            return html.nonDynamic[uri];
        }
        for (const route in allDynamicRoutes) {
            const { file, regex } = allDynamicRoutes[route];
            const re = new RegExp(regex, "i");
            const pathMatchesRoute = re.test(uri);
            if (pathMatchesRoute) {
                return file;
            }
        }
        if (html.nonDynamic["/404"] !== undefined) {
            return "pages/404.html";
        }
        return "pages/_error.js";
    }
    findFallbackRoute(resource) {
        const { pages: { ssr, html } } = this.manifest;
        const uri = resource.getNormalUri();
        if (ssr.nonDynamic[uri] || html.nonDynamic[uri]) {
            return undefined;
        }
        let foundFallback = undefined;
        const isNonFallbackDynamicRoute = Object.values(Object.assign(Object.assign({}, ssr.dynamic), html.dynamic)).find((dynamicRoute) => {
            if (foundFallback) {
                return false;
            }
            const re = new RegExp(dynamicRoute.regex);
            const matchesRegex = re.test(uri);
            if (matchesRegex) {
                const matchesFallbackRoute = Object.keys(this.prerenderManifest.dynamicRoutes).find((prerenderManifestRoute) => {
                    const fileMatchesPrerenderRoute = dynamicRoute.file === `pages${prerenderManifestRoute}.js`;
                    if (fileMatchesPrerenderRoute) {
                        foundFallback =
                            this.prerenderManifest.dynamicRoutes[prerenderManifestRoute];
                    }
                    return fileMatchesPrerenderRoute;
                });
                return !matchesFallbackRoute;
            }
            else {
                return false;
            }
        });
        if (isNonFallbackDynamicRoute) {
            return undefined;
        }
        if (foundFallback) {
            return foundFallback;
        }
        return Object.values(this.prerenderManifest.dynamicRoutes).find((routeConfig) => {
            const re = new RegExp(routeConfig.routeRegex);
            return re.test(uri);
        });
    }
}
exports.ResourceService = ResourceService;
