"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMetricsMediaClickData = exports.createMetricsMediaData = exports.createMetricsImpressionsData = exports.createMetricsSearchData = exports.createMetricsPageData = exports.createMetricsBackClickData = exports.createMetricsClickData = exports.MediaClickEventBuilder = exports.MediaEventBuilder = exports.ImpressionsEventBuilder = exports.SearchEventBuilder = exports.PageEventBuilder = exports.BackClickEventBuilder = exports.ClickEventBuilder = exports.EventBuilder = void 0;
const optional_1 = require("../types/optional");
// region Builders
/**
 * Base event builder.
 */
class EventBuilder {
    /**
     * Create base event builder with metrics configuration.
     *
     * @param configuration - Metrics configuration used to build metrics events.
     */
    constructor(configuration) {
        this.configuration = configuration;
        this.eventFields = {};
    }
    /**
     * Updates event builder with given event fields.
     * @param eventFields - The events fields to update in builder.
     * @returns Event builder with updated event fields.
     */
    withEventFields(eventFields) {
        this.eventFields = eventFields;
        return this;
    }
    /**
     * Updates event builder with given configuration.
     * @param configuration - The configuration to update in builder.
     * @returns Event builder with updated configuration.
     */
    withConfiguration(configuration) {
        this.configuration = configuration;
        return this;
    }
    /**
     * Updates event builder with given default topic.
     * @param topic - The default topic to update in builder.
     * @returns Event builder with updated default topic.
     */
    withDefaultTopic(topic) {
        this.configuration = {
            ...this.configuration,
            defaultTopic: topic,
        };
        return this;
    }
    /**
     * Updates event builder with given include fields requests.
     * @param includeRequests - The include fields requests to update in builder.
     * @returns Event builder with updated include fields requests.
     */
    withDefaultIncludeRequests(includeRequests) {
        this.configuration = {
            ...this.configuration,
            defaultIncludeRequests: includeRequests,
        };
        return this;
    }
    /**
     * Updates event builder with given exclude fields requests.
     * @param excludeRequests - The exclude fields requests to update in builder.
     * @returns Event builder with updated exclude fields requests.
     */
    withDefaultExcludeRequests(excludeRequests) {
        this.configuration = {
            ...this.configuration,
            defaultExcludeRequests: excludeRequests,
        };
        return this;
    }
    /**
     * Updates event builder with given flush behavior.
     * @param shouldFlush - The flush behavior to update in builder.
     * @returns Event builder with updated flush behavior.
     */
    withShouldFlush(shouldFlush) {
        this.configuration = {
            ...this.configuration,
            shouldFlush: shouldFlush,
        };
        return this;
    }
}
exports.EventBuilder = EventBuilder;
/**
 * Builder for click events.
 */
class ClickEventBuilder extends EventBuilder {
    /**
     * Create click metrics event builder with all required properties.
     *
     * @param options - Object containing options required to create the builder.
     *
     * Options:
     * - targetId - Target ID used for building events.
     * - targetType - Target type used for building events.
     * - configuration - Metrics configuration used to build metrics events.
     */
    constructor(options) {
        super(options.configuration);
        this.targetId = options.targetId;
        this.targetType = options.targetType;
    }
    /**
     * Updates event builder with given target ID.
     * @param targetId - The target ID to update in builder.
     * @returns Event builder with updated target ID.
     */
    withTargetId(targetId) {
        this.targetId = targetId;
        return this;
    }
    /**
     * Updates event builder with given target type.
     * @param targetType - The target type to update in builder.
     * @returns Event builder with updated target type.
     */
    withTargetType(targetType) {
        this.targetType = targetType;
        return this;
    }
    build() {
        return createMetricsClickData(this.targetId, this.targetType, this.eventFields, this.configuration);
    }
}
exports.ClickEventBuilder = ClickEventBuilder;
/**
 * Builder for back click events.
 */
class BackClickEventBuilder extends EventBuilder {
    build() {
        return createMetricsBackClickData(this.eventFields, this.configuration);
    }
}
exports.BackClickEventBuilder = BackClickEventBuilder;
/**
 * Builder for page events.
 */
class PageEventBuilder extends EventBuilder {
    /**
     * Create page metrics event builder with all required properties.
     *
     * @param configuration - Metrics configuration used to build metrics events.
     */
    constructor(configuration) {
        super(configuration);
        this.timingMetrics = {};
    }
    /**
     * Updates event builder with given fetch timing metrics.
     * @param timingMetrics - The fetch timing metrics to update in builder.
     * @returns Event builder with updated fetch timing metrics.
     */
    withTimingMetrics(timingMetrics) {
        this.timingMetrics = timingMetrics;
        return this;
    }
    build() {
        return createMetricsPageData(this.eventFields, this.timingMetrics, this.configuration);
    }
}
exports.PageEventBuilder = PageEventBuilder;
/**
 * Builder for search metrics events.
 */
class SearchEventBuilder extends EventBuilder {
    /**
     * Create search metrics event builder with all required properties.
     *
     * @param options - Object containing options required to create the builder.
     *
     * Options:
     * - term - Search term used to build metrics events.
     * - targetType - Target type used to build metrics events.
     * - actionType - Action type used to build metrics events.
     * - configuration - Metrics configuration used to build metrics events.
     */
    constructor(options) {
        super(options.configuration);
        this.term = options.term;
        this.targetType = options.targetType;
        this.actionType = options.actionType;
        this.actionUrl = null;
    }
    /**
     * Updates event builder with given search term.
     * @param term - The search term to update in builder.
     * @returns Event builder with updated search term.
     */
    withTerm(term) {
        this.term = term;
        return this;
    }
    /**
     * Updates event builder with given target type.
     * @param targetType - The target type to update in builder.
     * @returns Event builder with updated target type.
     */
    withTargetType(targetType) {
        this.targetType = targetType;
        return this;
    }
    /**
     * Updates event builder with given action type.
     * @param actionType - The action type to update in builder.
     * @returns Event builder with updated action type.
     */
    withActionType(actionType) {
        this.actionType = actionType;
        return this;
    }
    /**
     * Updates event builder with given action URL.
     * @param actionUrl - The action URL to update in builder.
     * @returns Event builder with updated action URL.
     */
    withActionUrl(actionUrl) {
        this.actionUrl = actionUrl;
        return this;
    }
    build() {
        return createMetricsSearchData(this.term, this.targetType, this.actionType, this.actionUrl, this.eventFields, this.configuration);
    }
}
exports.SearchEventBuilder = SearchEventBuilder;
/**
 * Builder for impressions events.
 */
class ImpressionsEventBuilder extends EventBuilder {
    constructor() {
        super(...arguments);
        /**
         * Impressions event version.
         */
        this.impressionsEventVersion = 4;
    }
    /**
     * Updates event builder with given impressions event version.
     * @param version - The impressions event version to update in builder.
     * @returns Event builder with updated impressions event version.
     */
    withImpressionsEventVersion(version) {
        this.impressionsEventVersion = version;
        return this;
    }
    build() {
        return createMetricsImpressionsData(this.eventFields, this.configuration, this.impressionsEventVersion);
    }
}
exports.ImpressionsEventBuilder = ImpressionsEventBuilder;
/**
 * Builder for media events.
 */
class MediaEventBuilder extends EventBuilder {
    build() {
        return createMetricsMediaData(this.eventFields, this.configuration);
    }
}
exports.MediaEventBuilder = MediaEventBuilder;
/**
 * Builder for media click events.
 */
class MediaClickEventBuilder extends EventBuilder {
    /**
     * Create media click event builder with all required properties.
     *
     * @param options - Object containing options required to create the builder.
     *
     * Options:
     * - targetId - Target ID used for building events.
     * - targetType - Target type used to build metrics events.
     * - configuration - Metrics configuration used to build metrics events.
     */
    constructor(options) {
        super(options.configuration);
        this.targetId = options.targetId;
        this.targetType = options.targetType;
    }
    /**
     * Updates event builder with given target ID.
     * @param targetId - The target ID to update in builder.
     * @returns Event builder with updated target ID.
     */
    withTargetId(targetId) {
        this.targetId = targetId;
        return this;
    }
    /**
     * Updates event builder with given target type.
     * @param targetType - The target type to update in builder.
     * @returns Event builder with updated target type.
     */
    withTargetType(targetType) {
        this.targetType = targetType;
        return this;
    }
    build() {
        return createMetricsMediaClickData(this.targetId, this.targetType, this.eventFields, this.configuration);
    }
}
exports.MediaClickEventBuilder = MediaClickEventBuilder;
// region Metrics Data
/**
 * Create metrics data for the click event.
 *
 * @param targetId - The ID of the click event target.
 * @param targetType - The type of the click target.
 * @param eventFields - Event fields to create metrics data from.
 * @param configuration - Metrics configuration used to create metrics data.
 */
function createMetricsClickData(targetId, targetType, eventFields, configuration) {
    const eventType = "click" /* MetricsEventType.click */;
    const fields = {
        ...eventFields,
        eventType: eventType,
        targetType: targetType,
        targetId: targetId,
    };
    return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsClickData = createMetricsClickData;
/**
 * Create metrics data for the Back button click event.
 *
 * @param eventFields - Event fields to create metrics data from.
 * @param configuration - Metrics configuration used to create metrics data.
 */
function createMetricsBackClickData(eventFields, configuration) {
    const fields = {
        ...eventFields,
        actionType: "back",
    };
    return createMetricsClickData("back", "button" /* MetricsClickTargetType.button */, fields, configuration);
}
exports.createMetricsBackClickData = createMetricsBackClickData;
/**
 * Create metrics data for the page event.
 * @param eventFields - Event fields to create metrics data from.
 * @param timingMetrics - The timing metrics for page data fetching.
 * @param configuration - Metrics configuration used to create metrics data.
 */
function createMetricsPageData(eventFields, timingMetrics, configuration) {
    const eventType = "page" /* MetricsEventType.page */;
    const fields = {
        ...eventFields,
        eventType: eventType,
        ...timingMetrics,
    };
    return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsPageData = createMetricsPageData;
/**
 * Create metrics data for search event.
 *
 * @param term - The search term.
 * @param target - The type of the acton target.
 * @param actionType - The type of the action.
 * @param actionUrl - An optional action URL.
 * @param eventFields - Event fields to create metrics data from.
 * @param configuration - Metrics configuration used to create metrics data.
 */
function createMetricsSearchData(term, targetType, actionType, actionUrl, eventFields, configuration) {
    const eventType = "search" /* MetricsEventType.search */;
    const fields = {
        ...eventFields,
        eventType: eventType,
        term: term,
        targetType: targetType,
        actionType: actionType,
    };
    if ((0, optional_1.isSome)(actionUrl)) {
        // actionUrl is defined for `hints` but not for searches fired from elsewhere.
        fields["actionUrl"] = actionUrl;
    }
    return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsSearchData = createMetricsSearchData;
/**
 * Create metrics data for impressions event.
 *
 * @param eventFields - Event fields to create metrics data from.
 * @param configuration - Metrics configuration used to create metrics data.
 * @param impressionsEventVersion - The version of the impressions event.
 */
function createMetricsImpressionsData(eventFields, configuration, impressionsEventVersion = 4) {
    const eventType = "impressions" /* MetricsEventType.impressions */;
    const fields = {
        ...eventFields,
        eventType: eventType,
        impressionQueue: "data-metrics",
        eventVersion: impressionsEventVersion,
    };
    return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsImpressionsData = createMetricsImpressionsData;
/**
 * Create metrics data for media event.
 *
 * @param eventFields - Event fields to create metrics data from.
 * @param configuration - Metrics configuration used to create metrics data.
 */
function createMetricsMediaData(eventFields, configuration) {
    const eventType = "media" /* MetricsEventType.media */;
    const fields = {
        ...eventFields,
        eventType: eventType,
    };
    return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsMediaData = createMetricsMediaData;
/**
 * Create metrics data for media event.
 *
 * @param targetId - The ID of the click target.
 * @param targetType - The type of the click target.
 * @param eventFields - Event fields to create metrics data from.
 * @param configuration - Metrics configuration used to create metrics data.
 */
function createMetricsMediaClickData(targetId, targetType, eventFields, configuration) {
    const eventType = "click" /* MetricsEventType.click */;
    const fields = {
        ...eventFields,
        eventType: eventType,
        targetType: targetType,
        targetId: targetId,
    };
    return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsMediaClickData = createMetricsMediaClickData;
// endregion
// region Helpers
function createMetricsData(fields, configuration, eventType) {
    return {
        fields: fields,
        includingFields: configuration.defaultIncludeRequests[eventType],
        excludingFields: configuration.defaultExcludeRequests[eventType],
        topic: topicFromEventFields(fields, configuration.defaultTopic),
        shouldFlush: (0, optional_1.isSome)(configuration.shouldFlush) ? configuration.shouldFlush(fields) : false,
    };
}
/**
 * Returns event topic for the given event fields.
 * @param eventFields - Event fields.
 * @param defaultTopic - An optional default topic to use if event fields doesn't have one.
 */
function topicFromEventFields(eventFields, defaultTopic) {
    const topic = eventFields["topic"];
    if ((0, optional_1.isSome)(topic)) {
        return topic;
    }
    return defaultTopic;
}
// endregion
//# sourceMappingURL=builder.js.map