import { isNothing } from "@jet/environment";
import * as models from "../../../../api/models/index";
import * as serverData from "../../../../foundation/json-parsing/server-data";
import * as mediaAttributes from "../../../../foundation/media/attributes";
import { createArtworkForResource } from "../../../content/artwork/artwork";
import * as contentAttributes from "../../../content/attributes";
import * as content from "../../../content/content";
import * as contentDeviceFamily from "../../../content/device-family";
import * as lockups from "../../../lockups/lockups";
import { translateItemsToV3 } from "./annotations";
export function createAnnotation(objectGraph, data, isFirstPartyHideableApp, isArcadeApp, suppressTitle, shelfMetrics) {
    const requirementsByDeviceFamily = mediaAttributes.attributeAsDictionary(data, "requirementsByDeviceFamily");
    let annotationItems = [];
    let requirementsSummary = defaultRequirementsSummaryFromData(objectGraph, data);
    const requiresRosetta = contentAttributes.contentAttributeAsBooleanOrFalse(objectGraph, data, "requiresRosetta", contentAttributes.defaultAttributePlatform(objectGraph));
    if (serverData.isDefinedNonNullNonEmpty(requirementsByDeviceFamily)) {
        // Create an annotation item for each of the device families in "requirementsByDeviceFamily"
        const deviceFamilies = sortedDeviceFamilies(objectGraph);
        for (const deviceFamily of deviceFamilies) {
            const deviceFamilyRequirements = serverData.asDictionary(requirementsByDeviceFamily, deviceFamily);
            if (serverData.isDefinedNonNullNonEmpty(deviceFamilyRequirements)) {
                // When Rosetta is not available, use a more specific requirements string explaining it's not available for the region.
                const preferRosettaUnavailableRequirementsString = objectGraph.appleSilicon.isSupportEnabled &&
                    deviceFamily === "mac" &&
                    requiresRosetta &&
                    !objectGraph.appleSilicon.isRosettaAvailable;
                const annotationItem = compatibilityAnnotationItemFromDeviceFamilyRequirements(objectGraph, deviceFamilyRequirements, preferRosettaUnavailableRequirementsString);
                if (serverData.isDefinedNonNull(annotationItem)) {
                    annotationItems.push(annotationItem);
                }
            }
        }
        // If `requirementsSummary` is null, this means we don't meet all the required capabilities
        // In this case, use the requirementsString for the first device family as the summary
        if (!serverData.isDefinedNonNull(requirementsSummary) && annotationItems.length > 0) {
            requirementsSummary = annotationItems[0].text;
        }
    }
    else {
        // If "requirementsByDeviceFamily" is empty or otherwise invalid, fall back to the legacy "requirementsString"
        const annotationItem = legacyCompatibilityAnnotationItemFromData(objectGraph, data);
        if (serverData.isDefinedNonNull(annotationItem)) {
            annotationItems = [annotationItem];
        }
    }
    if (serverData.isNullOrEmpty(annotationItems)) {
        return null;
    }
    const title = suppressTitle ? "" : objectGraph.loc.string("Requirements");
    const annotation = new models.Annotation(title, annotationItems, requirementsSummary);
    if (annotation.items_V3.length === 0) {
        annotation.items_V3 = translateItemsToV3(objectGraph, annotation);
    }
    if (preprocessor.GAMES_TARGET) {
        const supportedPlatforms = content.supportedAppPlatformsFromData(objectGraph, data);
        const isRunnableOnCurrentDevice = content.supportsPlatform(supportedPlatforms, content.currentAppPlatform(objectGraph));
        let systemImageName;
        if (!isRunnableOnCurrentDevice && supportedPlatforms.length > 0) {
            systemImageName = content.systemImageNameForAppPlatform(supportedPlatforms[0]);
        }
        else {
            systemImageName = content.systemImageNameForAppPlatform(content.currentAppPlatform(objectGraph));
        }
        annotation.leadingArtwork = createArtworkForResource(objectGraph, `systemimage://${systemImageName}`);
        annotation.prefersSmallLeadingArtwork = true;
    }
    else if (objectGraph.client.isVision) {
        annotation.leadingArtwork = createArtworkForResource(objectGraph, "systemimage://visionpro");
        annotation.prefersSmallLeadingArtwork = true;
    }
    return annotation;
}
/**
 * Returns a `DeviceFamily` list, in the order the device families should be displayed
 * This is based on a pre-defined sort order, and the current device type / model
 * @returns {contentDeviceFamily.DeviceFamily[]} A list of device families
 */
function sortedDeviceFamilies(objectGraph) {
    // Start with the default display order
    const deviceFamilies = [
        "iphone",
        "ipad",
        "ipod",
        "mac",
        "realityDevice",
        "tvos",
        "watch",
    ];
    // Now move our current device family to the start of the array
    const clientDeviceFamily = contentDeviceFamily.deviceFamilyFromDeviceType(objectGraph, objectGraph.client.deviceType, objectGraph.host.deviceModel);
    if (serverData.isDefinedNonNull(clientDeviceFamily)) {
        const indexOfClientDeviceFamily = deviceFamilies.indexOf(clientDeviceFamily);
        if (indexOfClientDeviceFamily > 0) {
            deviceFamilies.splice(indexOfClientDeviceFamily, 1);
            deviceFamilies.unshift(clientDeviceFamily);
        }
    }
    return deviceFamilies;
}
/**
 * Returns the default requirements summary, eg. "Works on this iPhone"
 * Currently only returns a value if the device has all required capabilities
 *
 * @param data MAPI data to build the summary with.
 * @returns {string} The requirements summary
 */
function defaultRequirementsSummaryFromData(objectGraph, data) {
    let requirementsSummary;
    if (lockups.deviceHasCapabilitiesFromData(objectGraph, data)) {
        const supportsMacOSCompatibleIOSBinary = content.supportsMacOSCompatibleIOSBinaryFromData(objectGraph, data, objectGraph.appleSilicon.isSupportEnabled);
        const supportsVisionOSCompatibleIOSBinary = content.supportsVisionOSCompatibleIOSBinaryFromData(objectGraph, data);
        const supportedAppPlatforms = content.supportedAppPlatformsFromData(objectGraph, data);
        const isMacOSAppRunnable = content.isMacOSAppBuyableAndRunnableFromData(objectGraph, data, objectGraph.appleSilicon.isSupportEnabled, objectGraph.appleSilicon.isRosettaAvailable);
        const isThisDeviceSupported = content.runnableOnDevice(objectGraph, supportedAppPlatforms, objectGraph.client.deviceType, supportsMacOSCompatibleIOSBinary, supportsVisionOSCompatibleIOSBinary, isMacOSAppRunnable);
        const deviceName = objectGraph.loc.deviceDisplayName(objectGraph);
        if (isThisDeviceSupported && deviceName) {
            const requirementsSummaryReplacement = objectGraph.loc.string("InfoList.Requirements.Summary");
            requirementsSummary = requirementsSummaryReplacement.replace("{deviceName}", deviceName);
        }
    }
    return requirementsSummary;
}
/**
 * Creates an annotation item from a set of requirements for a specific device family
 *
 * @param {JSONData} deviceFamilyData data to build the annotation item with
 * @param {boolean} preferRosettaUnavailableRequirementsString Use more specific Rosetta unavailable requirements string.
 * @returns {models.AnnotationItem} The annotation item
 */
function compatibilityAnnotationItemFromDeviceFamilyRequirements(objectGraph, deviceFamilyData, preferRosettaUnavailableRequirementsString) {
    var _a;
    const deviceFamilyName = (_a = serverData.asString(deviceFamilyData, "deviceFamily")) !== null && _a !== void 0 ? _a : undefined;
    let requirementsString = serverData.asString(deviceFamilyData, "requirementString");
    const devices = serverData.asArrayOrEmpty(deviceFamilyData, "devices");
    // When Rosetta is not available, use a more specific requirements string explaining it's not available for the region.
    if (preferRosettaUnavailableRequirementsString) {
        const rosettaUnavailableRequirementsString = serverData.asString(deviceFamilyData, "rosettaUnavailableRequirementString");
        if (serverData.isDefinedNonNullNonEmpty(rosettaUnavailableRequirementsString)) {
            requirementsString = rosettaUnavailableRequirementsString;
        }
    }
    if (isNothing(requirementsString)) {
        return null;
    }
    // Combine list of devices into a bullet list
    const deviceListItems = [];
    for (const device of devices) {
        // Wrap the device name in a FSI/PDI unicode pair, to ensure it maintains it's correct direction
        // in both LTR and RTL environments
        deviceListItems.push("\u2022\t\u2068" + device + "\u2069");
    }
    const devicesList = deviceListItems.length > 0 ? deviceListItems.join("\n") : undefined;
    return new models.AnnotationItem(requirementsString, { heading: deviceFamilyName, listText: devicesList });
}
/**
 * Creates an annotation item from the "requirementsString" text string
 * This is only used in fallback scenarios, where "requirementsByDeviceFamily" is empty or invalid
 *
 * @param data MAPI data to build the annotation item with
 * @returns {models.AnnotationItem} The annotation item
 */
function legacyCompatibilityAnnotationItemFromData(objectGraph, data) {
    const requirements = contentAttributes.contentAttributeAsString(objectGraph, data, "requirementsString");
    if (serverData.isNull(requirements)) {
        return null;
    }
    return new models.AnnotationItem(requirements);
}
//# sourceMappingURL=compatibility-annotation.js.map