"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Track = void 0;
const uuid_1 = require("./edge-decider/lib/uuid");
const device_source_1 = require("./edge-decider/lib/device_source");
const TRACKING_HOST = 'https://logx.optimizely.com/v1/events';
const CLIENT_NAME = 'ed-cf'; //edge-delivery, cloudflare
var CLIENT_ACTIVATION_EVENT_NAME = 'client_activation';
var CAMPAIGN_ACTIVATED_EVENT = 'campaign_activated';
var VIEW_ACTIVATED_TYPE = 'view_activated';
class Track {
    constructor(context, inputs, config, packageVersion, visitorId) {
        this.context = context;
        this.inputs = inputs;
        this.config = config;
        this.packageVersion = packageVersion;
        this.visitorId = visitorId;
    }
    getUserFeatures() {
        let features = {};
        features['browserId'] = this.inputs.metadata.parsedUA?.browser.id;
        features['browserVersion'] = this.inputs.metadata.parsedUA?.browser?.version;
        features['device'] = (0, device_source_1.getDevice)(this.inputs.metadata.parsedUA
            ?.device);
        features['cookies'] = JSON.stringify(this.inputs.cookies) ?? '';
        features['first_session'] = JSON.stringify(this.inputs.first_session);
        features['language'] = this.inputs.language ?? '';
        features['IP'] = this.inputs.visitorIp;
        features['queryParams'] = this.inputs.queryParams
            ? new URLSearchParams(this.inputs.queryParams).toString()
            : '';
        features['location'] = this.inputs.location;
        features['visitorId'] = this.visitorId;
        let result = [];
        for (let key in features) {
            if (features.hasOwnProperty(key)) {
                result.push({
                    e: null,
                    k: '',
                    t: key,
                    v: features[key], // value: 'v',
                });
            }
        }
        return result;
    }
    trackClientActivation(logger) {
        let visitorAttr = this.getUserFeatures();
        let now = Date.now();
        var event = {
            e: null,
            t: now,
            u: (0, uuid_1.generate)(),
            y: CLIENT_ACTIVATION_EVENT_NAME,
        };
        let snapshots = [
            {
                decisions: [],
                events: [event],
            },
        ];
        //TODO: will there ever be more than one visitor? visitor[ attributes[], snapshots[] ]
        //opti tracker's visitor store's "Current" visitor = last visitor in list
        let payload = this.formatPayloadData(visitorAttr, snapshots, logger);
        logger.debug('=== Sending track client activation payload:', payload);
        this.sendTrackEvent(this.context, payload, logger);
    }
    trackCampaignPageActivated(decisions, logger, timestamp) {
        if (!decisions || decisions.length == 0) {
            logger.debug('Not sending campaign/page view payload due to no decisions made');
            return;
        }
        let visitorAttr = this.getUserFeatures();
        let snapshotDecisions = decisions.map(decisionData => {
            return {
                c: decisionData.layerId,
                x: decisionData.experimentId,
                v: decisionData.variationId,
                h: decisionData.isLayerHoldback || false,
            };
        });
        let campaignEvent = decisions.map(decisionData => {
            return {
                u: (0, uuid_1.generate)(),
                e: decisionData.layerId,
                t: timestamp,
                y: CAMPAIGN_ACTIVATED_EVENT,
            };
        });
        let viewEvent = decisions.map(decisionData => {
            let apiName = this.config.views.find(view => view.id === decisionData.viewId)?.apiName;
            return {
                e: decisionData.viewId,
                k: apiName,
                t: timestamp,
                u: (0, uuid_1.generate)(),
                y: VIEW_ACTIVATED_TYPE,
                a: {}, //TODO eventTags = formatTagsAndMetrics(viewEventData.eventTags)
                //                             'q': decision.quantity, //quantity
                //                             '$': decision.revenue, //revenue
                //                             'a': decision.tags, //tags
                //                             'v': decision.value, //value
            };
        });
        let decisionPayload = this.formatPayloadData(visitorAttr, [
            { decisions: snapshotDecisions, events: campaignEvent },
            { decisions: snapshotDecisions, events: viewEvent },
        ], logger);
        logger.debug('=== Sending campaign/page view payload:', decisionPayload);
        this.sendTrackEvent(this.context, decisionPayload, logger);
    }
    formatPayloadData(attributes, snapshots, logger) {
        try {
            return JSON.stringify({
                account_id: this.config.accountId,
                anonymize_ip: this.config.anonymizeIP,
                client_name: CLIENT_NAME,
                client_version: this.packageVersion,
                project_id: this.config.projectId,
                revision: this.config.revision,
                visitors: [
                    {
                        visitor_id: this.visitorId,
                        session_id: 'AUTO',
                        attributes: attributes,
                        snapshots: snapshots,
                    },
                ],
            });
        }
        catch (e) {
            logger.error('Error formatting payload data', e);
            return null;
        }
    }
    async sendTrackEvent(context, payload, logger) {
        context.waitUntil(fetch(TRACKING_HOST, {
            method: 'POST',
            headers: {
                'content-type': 'application/json',
                'X-Optimizely-Strict': 'true',
            },
            body: payload,
        }).then(response => {
            return response
                .text()
                .then(body => {
                logger.debug('Fetch succeeded ', response.status, body);
            })
                .catch(error => {
                logger.debug('Fetch failed:', response.status, error);
            });
        }));
        return;
    }
}
exports.Track = Track;
