"use strict";
/**
 * Copyright (c) 2022 Google LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.i18nContentOptions = void 0;
const pathutils_1 = require("./pathutils");
/**
 * Returns the list of paths to check for i18n content.
 * The path order is:
 * (1) root/language_country/path (for each language)
 * (2) root/ALL_country/path (if country is set)
 * (3) root/language_ALL/path or root/language/path (for each language)
 *
 * If i18n is *not* configured, an empty list is returned.
 * @param p requested path.
 * @param req the request object containing superstatic and i18n configuration.
 * @return list of paths to check for i18n content.
 */
function i18nContentOptions(p, req) {
    const paths = [];
    const i18n = req.superstatic.i18n;
    if (!i18n || !i18n.root) {
        return paths;
    }
    const country = getCountryCode(req.headers);
    const languages = getI18nLanguages(req.headers);
    // (1)
    if (country) {
        for (const l of languages) {
            paths.push(join(i18n.root, `${l}_${country}`, p));
        }
        // (2)
        paths.push(join(i18n.root, `ALL_${country}`, p));
    }
    // (3)
    for (const l of languages) {
        paths.push(join(i18n.root, `${l}_ALL`, p));
        paths.push(join(i18n.root, `${l}`, p));
    }
    return paths;
}
exports.i18nContentOptions = i18nContentOptions;
function join(...arr) {
    arr.unshift("/");
    return (0, pathutils_1.normalizeMultiSlashes)(arr.join("/"));
}
/**
 * Fetches the country code from the headers object.
 * @param headers headers from the request.
 * @return country code, or an empty string.
 */
function getCountryCode(headers) {
    const overrideValue = cookieValue(headers.cookie, "firebase-country-override");
    if (overrideValue) {
        return overrideValue;
    }
    return headers["x-country-code"] || "";
}
/**
 * Fetches the languages from the accept-language header.
 * @param headers headers from the request.
 * @return ordered list of languages from the header.
 */
function getI18nLanguages(headers) {
    const overrideValue = cookieValue(headers.cookie, "firebase-language-override");
    if (overrideValue) {
        return overrideValue.includes(",")
            ? overrideValue.split(",")
            : [overrideValue];
    }
    const acceptLanguage = headers["accept-language"];
    if (!acceptLanguage) {
        return [];
    }
    const languagesSeen = new Set();
    const languagesOrdered = [];
    for (const v of acceptLanguage.split(",")) {
        const l = v.split("-")[0];
        if (!l) {
            continue;
        }
        if (!languagesSeen.has(l)) {
            languagesOrdered.push(l);
        }
        languagesSeen.add(l);
    }
    return languagesOrdered;
}
/**
 * Fetches a value from a cookie string.
 * @param cookieString full cookie string.
 * @param key key to look for.
 * @return the value, or empty string;
 */
function cookieValue(cookieString, key) {
    if (!cookieString) {
        return "";
    }
    const cookies = cookieString.split(";").map((c) => c.trim());
    for (const cookie of cookies) {
        if (cookie.startsWith(key)) {
            const s = cookie.split("=", 2);
            return s.length === 2 ? s[1] : "";
        }
    }
    return "";
}
