import * as validation from "@jet/environment/json/validation";
import * as models from "../api/models";
import * as serverData from "../foundation/json-parsing/server-data";
import { isNothing } from "@jet/environment";
import * as mediaDataFetching from "../foundation/media/data-fetching";
import * as client from "../foundation/wrappers/client";
import { contentAttributeAsDictionary } from "./content/attributes";
import * as content from "./content/content";
/**
 * Creates a category list context for child categories of a provided genre, e.g. Games or Apps.
 *
 * @param rootGenreId  The genreId that describes the parent of the category list, regardless of whether the root is included in the list.
 * @returns The created category list context, e.g. Apps, Games, or All.
 */
export function createContextFromGenre(rootGenreId) {
    if (rootGenreId === 36 /* constants.GenreIds.Apps */.toString()) {
        return 1 /* models.CategoryListContext.Apps */;
    }
    else if (rootGenreId === 6014 /* constants.GenreIds.Games */.toString()) {
        return 2 /* models.CategoryListContext.Games */;
    }
    else {
        return 0 /* models.CategoryListContext.All */;
    }
}
/**
 * Create a category list context for given categories by inspecting the first item, e.g. "All Games", "All Apps".
 *
 * @param categoryList The category list to create a category list context for.
 * @returns The created category list context, e.g. Apps, Games, or All.
 */
export function createContextFromList(categoryList) {
    const categories = categoryList.categories;
    if (serverData.isDefinedNonNullNonEmpty(categories)) {
        const firstCategoryGenreId = categories[0].genreId;
        if (firstCategoryGenreId === 6014 /* constants.GenreIds.Games */.toString()) {
            return 2 /* models.CategoryListContext.Games */;
        }
        else if (firstCategoryGenreId === 36 /* constants.GenreIds.Apps */.toString()) {
            return 1 /* models.CategoryListContext.Apps */;
        }
    }
    return 0 /* models.CategoryListContext.All */;
}
export function createRequest(objectGraph, genreId, clientIdentifier = objectGraph.host.clientIdentifier, additionalPlatforms = []) {
    if (!genreId) {
        genreId = objectGraph.client.isMac ? 39 /* constants.GenreIds.MacApps */ : 36 /* constants.GenreIds.Apps */;
    }
    const categoriesRequest = new mediaDataFetching.Request(objectGraph)
        .forType("categories")
        .includingAdditionalPlatforms(additionalPlatforms)
        .includingMacOSCompatibleIOSAppsWhenSupported(true)
        .includingAgeRestrictions()
        .addingQuery("genre", `${genreId}`);
    if (clientIdentifier === client.watchIdentifier) {
        categoriesRequest.addingContext("watch");
    }
    else if (clientIdentifier === client.messagesIdentifier) {
        categoriesRequest.addingContext("messages");
    }
    return categoriesRequest;
}
/**
 * Creates a category list model from a server response.
 *
 * @param objectGraph The dependency graph for the App Store.
 * @param response  The JSON data returned by the server.
 * @param includeRoot Whether or not to include the root category in the subcategory list, e.g. "All".
 * @returns The created category list model.
 */
export function categoryListFromApiResponse(objectGraph, response, includeRoot = true) {
    return validation.context("categoryListFromApiResponse", () => {
        const categoriesData = serverData.asArrayOrEmpty(response, "results.categories");
        const rootCategory = categoryFromApiResponse(objectGraph, serverData.asDictionary(categoriesData, "0"), includeRoot);
        if (!rootCategory) {
            return null;
        }
        return new models.CategoryList(rootCategory.children);
    });
}
/**
 * Creates a category model from a server response.
 *
 * @param objectGraph The dependency graph for the App Store.
 * @param categoryData The JSON data from the server response for this individual category item.
 * @param includeRoot  Whether or not to include the root category in the child categories, e.g. "All".
 * @returns The created category model.
 */
export function categoryFromApiResponse(objectGraph, categoryData, includeRoot = true) {
    return validation.context("categoryFromApiResponse", () => {
        if (!categoryData) {
            return null;
        }
        const name = serverData.asString(categoryData, "name");
        const genre = serverData.asString(categoryData, "genre");
        const ages = serverData.asString(categoryData, "ages");
        const artwork = content.artworkFromApiArtwork(objectGraph, serverData.asDictionary(categoryData, "artwork"), {
            allowingTransparency: true,
            useCase: 20 /* content.ArtworkUseCase.CategoryIcon */,
        });
        const children = serverData
            .asArrayOrEmpty(categoryData, "children")
            .map((childCategory) => {
            return categoryFromApiResponse(objectGraph, serverData.asDictionary(childCategory), includeRoot);
        })
            .filter((category) => serverData.isDefinedNonNull(category));
        const sortedChildren = sortCategories(objectGraph, children);
        const label = serverData.asString(categoryData, "label");
        if (label && includeRoot) {
            // Add root to children to show "All" category
            sortedChildren.unshift(new models.Category(label, genre, artwork, ages, []));
        }
        return new models.Category(name, genre, artwork, ages, sortedChildren);
    });
}
function sortCategories(objectGraph, categories) {
    return categories.sort((category1, category2) => {
        try {
            return category1.name.localeCompare(category2.name, objectGraph.loc.safeIdentifier, { usage: "sort" });
        }
        catch (e) {
            return 0;
        }
    });
}
export function searchAdditionalPlatforms(objectGraph) {
    switch (objectGraph.client.deviceType) {
        case "pad":
            return ["iphone"];
        default:
            return [];
    }
}
export function categoryArtworkData(objectGraph, data, isMonochrome = false, forceFallbackArtwork = false, allowFallback = true) {
    const attributePath = isMonochrome ? "contentIconTrimmedMonochrome" : "contentIconTrimmed";
    const fallbackAttributePath = "brandLogo";
    const editorialArtwork = contentAttributeAsDictionary(objectGraph, data, "editorialArtwork");
    if (forceFallbackArtwork) {
        return serverData.asDictionary(editorialArtwork, fallbackAttributePath);
    }
    else {
        let artworkData = serverData.asDictionary(editorialArtwork, attributePath);
        if (allowFallback && isNothing(artworkData)) {
            artworkData = serverData.asDictionary(editorialArtwork, fallbackAttributePath);
        }
        return artworkData;
    }
}
//# sourceMappingURL=categories.js.map