import * as models from "../../api/models";
import * as serverData from "../../foundation/json-parsing/server-data";
import { ResponseMetadata } from "../../foundation/network/network";
/**
 * Creates a new `PageRefreshController` with the provided information.
 * @param response the response from the network request.
 * @param refreshWhileVisibleForNextPreferredContentRefreshDate indicates that the page supports refreshing while visible, but only where the nextPreferredContentRefreshDate is used as the refresh date.
 * @returns a `PageRefreshController`.
 */
export function newPageRefreshControllerFromResponse(response, refreshWhileVisibleForNextPreferredContentRefreshDate = false) {
    return {
        timeToLive: timeToLiveFromResponse(response),
        nextPreferredContentRefreshDate: null,
        refreshWhileVisibleForNextPreferredContentRefreshDate: refreshWhileVisibleForNextPreferredContentRefreshDate,
    };
}
/**
 * Creates a new `PageRefreshController`.
 * This is primarily used for shelf hydration where we don't have a full page response to use for TTL data.
 * @returns an empty `PageRefreshController`.
 */
export function newPageRefreshController() {
    return {
        timeToLive: null,
        nextPreferredContentRefreshDate: null,
        refreshWhileVisibleForNextPreferredContentRefreshDate: false,
    };
}
/**
 * Adds a preferredContentRefreshDate to the refreshController if it's sooner than the currently known nextPreferredContentRefreshDate.
 * Provided date must be in the future.
 * @param nextPreferredContentRefreshDate the new date to check and add.
 * @param refreshController the refreshController to add the new date to
 */
export function addNextPreferredContentRefreshDate(newPreferredContentRefreshDate, refreshController) {
    if (serverData.isNull(refreshController) || serverData.isNull(newPreferredContentRefreshDate)) {
        return;
    }
    if ((serverData.isNull(refreshController.nextPreferredContentRefreshDate) ||
        newPreferredContentRefreshDate.getTime() < refreshController.nextPreferredContentRefreshDate.getTime()) &&
        newPreferredContentRefreshDate.getTime() > new Date().getTime()) {
        refreshController.nextPreferredContentRefreshDate = newPreferredContentRefreshDate;
    }
}
/**
 * Generates a `PageRefreshPolicy` that can be attached to a page to define the refresh logic of that page.
 * @param refreshController the object that has collected data to create a suitable refresh policy
 * @returns the refresh policy, if a content TTL or nextPreferredContentRefreshDate has been provided.
 */
export function pageRefreshPolicyForController(objectGraph, refreshController) {
    if (!isAutomaticPageRefreshEnabled(objectGraph)) {
        return null;
    }
    if (serverData.isNull(refreshController)) {
        return null;
    }
    let date;
    let usingNextPreferredContentRefreshDate = false;
    if (serverData.isDefinedNonNull(refreshController.timeToLive) &&
        serverData.isDefinedNonNull(refreshController.nextPreferredContentRefreshDate)) {
        const timeToLiveDate = dateByAddingTimeToNow(refreshController.timeToLive);
        if (timeToLiveDate.getTime() < refreshController.nextPreferredContentRefreshDate.getTime() &&
            timeToLiveDate.getTime() > new Date().getTime()) {
            date = timeToLiveDate;
        }
        else {
            date = refreshController.nextPreferredContentRefreshDate;
            usingNextPreferredContentRefreshDate = true;
        }
    }
    else if (serverData.isDefinedNonNull(refreshController.timeToLive)) {
        date = dateByAddingTimeToNow(refreshController.timeToLive);
    }
    else if (serverData.isDefinedNonNull(refreshController.nextPreferredContentRefreshDate)) {
        date = refreshController.nextPreferredContentRefreshDate;
        usingNextPreferredContentRefreshDate = true;
    }
    else {
        return null;
    }
    if (date.getTime() <= new Date().getTime()) {
        return null;
    }
    const refreshWhileVisible = usingNextPreferredContentRefreshDate && refreshController.refreshWhileVisibleForNextPreferredContentRefreshDate;
    return new models.PageRefreshPolicy("timeToLive", 0.0, null, date, refreshWhileVisible);
}
/**
 * Returns the nextPreferredContentRefreshDate for the provided refresh controller.
 * Primarily used when fetching individual shelves so we can attach a refresh date, rather
 * than a `PageRefreshPolicy`, which sits up at a page level.
 * @param refreshController the object that has collected refresh data.
 * @returns the nextPreferredContentRefreshDate, if it has been provided.
 */
export function nextPreferredContentRefreshDateForController(refreshController) {
    return refreshController === null || refreshController === void 0 ? void 0 : refreshController.nextPreferredContentRefreshDate;
}
/**
 * Returns the time to live value from the response data.
 *
 * @param dataContainer The response data container from which to extract the content TTL
 * @returns a content TTL, if any, or null.
 */
function timeToLiveFromResponse(response) {
    return response[ResponseMetadata.contentMaxAge];
}
/**
 * Returns a new date, adjusted by the number of seconds.
 *
 * @param seconds The number of seconds to add to now
 * @returns The adjusted Date
 */
function dateByAddingTimeToNow(seconds) {
    const date = new Date();
    date.setSeconds(date.getSeconds() + seconds);
    return date;
}
/**
 * Returns whether refreshing pages automatically is enabled in the bag.
 */
function isAutomaticPageRefreshEnabled(objectGraph) {
    return objectGraph.bag.enableAutomaticPageRefresh;
}
//# sourceMappingURL=page-refresh-controller.js.map