import { noContentError, notFoundError } from "./network";
/**
 * Validate an untrusted adam ID without contacting the server.
 *
 * This allows avoiding the work of calling the server with completely bogus
 * IDs. It's scoped to web since ID formats can change and web can be updated
 * easily (whereas backporting to older native clients is trickier).
 *
 * @param {AppStoreObjectGraph} objectGraph
 * @param {string} id - the Adam ID to validate
 * @returns {void} undefined if valid, throws a `NetworkError` (204) otherwise
 */
export function validateAdamId(objectGraph, id) {
    if (objectGraph.client.isWeb && !isAdamId(id)) {
        throw noContentError();
    }
}
/**
 * Check if an ID is a valid Adam ID.
 *
 * @param {string} id - string to validate
 * @return {boolean} true if valid, false otherwise
 */
function isAdamId(id) {
    // Media API actually validates if the number <= 2^63-1. But doubles in
    // JavaScript cannot precisely represent this (the closest number is >2^63)
    // so checking this requires BigInt, which might not be available. At the
    // end of the day, checking this is likely not worth the complexity. 2^63-1
    // is 9223372036854775807 so we just restrict the number of digits.
    //
    // See: https://github.pie.apple.com/its/amp-enums/blob/f75500b44f871f35ba3ce459a5ff4c9f225e71b0/src/main/java/com/apple/jingle/store/IdSpace.java#L131-L140
    // See: https://github.com/google/guava/blob/869a75a1e3ff85d36672a3cd154772dc90c7b3d2/guava/src/com/google/common/primitives/Longs.java#L400-L440
    // See: https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/lang/Long.html#MAX_VALUE
    return /^\d{1,19}$/.test(id);
}
/**
 * Validate an untrusted Featured Content ID without contacting the server.
 *
 * This allows avoiding the work of calling the server with completely bogus
 * IDs. It's scoped to web since ID formats can change and web can be updated
 * easily (whereas backporting to older native clients is trickier).
 *
 * @param {AppStoreObjectGraph} objectGraph
 * @param {string} id the FC ID to validate
 * @returns {void} undefined if valid, throws a `NetworkError` (204) otherwise
 */
export function validateFcId(objectGraph, id) {
    if (objectGraph.client.isWeb && !isFcId(id)) {
        throw noContentError();
    }
}
/**
 * Check if an ID is a valid Featured Content (FC) ID.
 *
 * @param {string} id - string to validate
 * @return {boolean} true if valid, false otherwise
 */
function isFcId(id) {
    // FcIds are actually Adam IDs under the hood.
    // See: https://github.pie.apple.com/its/Jingle/blob/d2d051c9ef2891f72d5f02f5bbbf2d7748afa7b9/MZStoreComponents/src/main/java/com/apple/jingle/app/store/editorial/SFEditorialHelper.java#L293
    return isAdamId(id);
}
/**
 * Validate an untrusted (Chart) Genre ID without contacting the server.
 *
 * This allows avoiding the work of calling the server with completely bogus
 * IDs. It's scoped to web since ID formats can change and web can be updated
 * easily (whereas backporting to older native clients is trickier).
 *
 * @param {AppStoreObjectGraph} objectGraph
 * @param {string} id the genre ID to validate
 * @returns {void} undefined if valid, throws a `NetworkError` (204) otherwise
 */
export function validateGenreId(objectGraph, id) {
    if (objectGraph.client.isWeb && !isGenreId(id)) {
        throw noContentError();
    }
}
/**
 * Check if an ID is a valid (Chart) Genre ID.
 *
 * @param {string} id - string to validate
 * @return {boolean} true if valid, false otherwise
 */
function isGenreId(id) {
    // Genre IDs are Java int (signed 32-bit).
    //
    // Technically negative is not excluded, but all charts are positive, so
    // filter out negative.
    //
    // See: https://github.pie.apple.com/its/Jingle/blob/main/shared/reference-data-logic/MZReferenceDataLogic/src/main/java/com/apple/jingle/eo/MZGenreService.java#L555
    return isPositiveJavaInt(id);
}
/**
 * Validate an untrusted Grouping ID without contacting the server.
 *
 * This allows avoiding the work of calling the server with completely bogus
 * IDs. It's scoped to web since ID formats can change and web can be updated
 * easily (whereas backporting to older native clients is trickier).
 *
 * @param {AppStoreObjectGraph} objectGraph
 * @param {string} id the grouping ID to validate
 * @returns {void} undefined if valid, throws a `NetworkError` (204) otherwise
 */
export function validateGroupingId(objectGraph, id) {
    if (objectGraph.client.isWeb && !isGroupingId(id)) {
        throw noContentError();
    }
}
/**
 * Check if an ID is a valid Grouping ID.
 *
 * @param {string} id - string to validate
 * @return {boolean} true if valid, false otherwise
 */
function isGroupingId(id) {
    // Grouping IDs are Java int (signed 32-bit)
    //
    // Technically negative does not fail to parse, but they're all positive in
    // practice.
    //
    // See: https://github.pie.apple.com/its/Jingle/blob/aaccec936f1feed227fd171ae66bb160cf38e497/MZStorePlatform/src/main/java/com/apple/jingle/store/mediaapi/util/SFMediaAPIEditorialUtil.java#L634
    return isPositiveJavaInt(id);
}
/**
 * Test if a string contains a Java int.
 *
 * @param {string} s - the string to test
 * @returns {boolean} true if the string is a stringified Java int, false otherwise
 */
function isPositiveJavaInt(s) {
    // Java int is 32-bit signed. We can check bounds since signed integers are
    // exactly representable as doubles (actually up to 2^53 is representable
    // exactly).
    //
    // See: https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/lang/Integer.html#MAX_VALUE
    return /^\d+$/.test(s) && parseInt(s, 10) <= 2147483647;
}
/**
 * Validate an untrusted Editorial Shelf Collection ID without contacting the server.
 *
 * This allows avoiding the work of calling the server with completely bogus
 * IDs. It's scoped to web since ID formats can change and web can be updated
 * easily (whereas backporting to older native clients is trickier).
 *
 * @param {AppStoreObjectGraph} objectGraph
 * @param {string} id the editorial shelf collection ID to validate
 * @returns {void} undefined if valid, throws a `NetworkError` (204) otherwise
 */
export function validateEditorialShelfCollectionId(objectGraph, id) {
    if (objectGraph.client.isWeb && !isEditorialShelfCollectionId(id)) {
        throw noContentError();
    }
}
/**
 * Check if an ID is a valid editorial shelf collection ID.
 *
 * @param {string} id - string to validate
 * @return {boolean} true if valid, false otherwise
 */
function isEditorialShelfCollectionId(id) {
    // Ids are prefixed with "eds.". Beyond that they do have a UUID-type
    // identifier that follows, but that seems more liable to change.
    //
    // See: https://github.pie.apple.com/its/amp-enums/blob/f75500b44f871f35ba3ce459a5ff4c9f225e71b0/src/main/java/com/apple/jingle/store/IdSpace.java#L43C5-L43C20
    // See: https://github.pie.apple.com/its/amp-enums/blob/f75500b44f871f35ba3ce459a5ff4c9f225e71b0/src/main/java/com/apple/jingle/store/IdSpace.java#L250-L252
    return id.startsWith("eds.");
}
/**
 * Validates if a request can be performed for `vision` platform content, based on
 * the feature flag is disabled.
 *
 * @param {AppStoreObjectGraph} objectGraph The application's state graph.
 * @throws {NetworkError} Throws a 404 error if access is restricted.
 * @returns {void}
 */
export function validateNeedsVisionRestriction(objectGraph) {
    var _a;
    if (objectGraph.client.isWeb &&
        ((_a = objectGraph.activeIntent) === null || _a === void 0 ? void 0 : _a.previewPlatform) === "vision" &&
        !objectGraph.bag.enableVisionPlatform) {
        throw notFoundError();
    }
}
//# sourceMappingURL=util.js.map