"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const common_fields_1 = require("./common-fields");
const client_1 = require("./client");
const actions_core_1 = require("@segment/actions-core");
const dynamic_field_functions_1 = require("./functions/dynamic-field-functions");
const types_1 = require("./types");
const hubspot_event_schema_functions_1 = require("./functions/hubspot-event-schema-functions");
const event_completion_functions_1 = require("./functions/event-completion-functions");
const validation_functions_1 = require("./functions/validation-functions");
const schema_functions_1 = require("./functions/schema-functions");
const cache_functions_1 = require("./functions/cache-functions");
const action = {
    title: 'Custom Event V2',
    description: 'Send Custom Events to HubSpot',
    syncMode: {
        description: 'Specify how Segment should update event schemas in Hubspot',
        label: 'Sync Mode',
        default: 'update',
        choices: [
            { label: 'Create new and update existing custom event definitions', value: 'upsert' },
            { label: 'Create new, but do not update existing custom event definitions', value: 'add' },
            { label: 'Update existing, but do not create new custom event definitions', value: 'update' }
        ]
    },
    fields: {
        ...common_fields_1.commonFields
    },
    dynamicFields: dynamic_field_functions_1.dynamicFields,
    perform: async (request, { payload, syncMode, subscriptionMetadata, statsContext, logger }) => {
        return await send(request, payload, syncMode, subscriptionMetadata, statsContext, logger);
    }
};
const send = async (request, payload, syncMode, subscriptionMetadata, statsContext, logger) => {
    statsContext?.tags?.push('action:custom_event');
    const client = new client_1.Client(request);
    const validPayload = (0, validation_functions_1.validate)(payload, statsContext, logger, subscriptionMetadata);
    const schema = (0, schema_functions_1.eventSchema)(validPayload);
    const cachedSchema = (0, cache_functions_1.getSchemaFromCache)(schema.name, subscriptionMetadata, statsContext);
    statsContext?.statsClient?.incr(`cache.get.${cachedSchema === undefined ? 'miss' : 'hit'}`, 1, statsContext?.tags);
    const cacheSchemaDiff = (0, cache_functions_1.compareSchemas)(schema, cachedSchema);
    statsContext?.statsClient?.incr(`cache.diff.${cacheSchemaDiff.match}`, 1, statsContext?.tags);
    if (cacheSchemaDiff.match === types_1.SchemaMatch.FullMatch) {
        (0, cache_functions_1.convertNumericStrings)(validPayload, cacheSchemaDiff.numericStrings);
        return await (0, event_completion_functions_1.sendEvent)(client, cachedSchema.fullyQualifiedName, validPayload);
    }
    const hubspotSchema = await (0, hubspot_event_schema_functions_1.getSchemaFromHubspot)(client, schema);
    statsContext?.statsClient?.incr(`hubspotSchema.get.${hubspotSchema === undefined ? 'miss' : 'hit'}`, 1, statsContext?.tags);
    const hubspotSchemaDiff = (0, cache_functions_1.compareSchemas)(schema, hubspotSchema);
    statsContext?.statsClient?.incr(`hubspotSchemaDiff.diff.${hubspotSchemaDiff.match}`, 1, statsContext?.tags);
    (0, cache_functions_1.convertNumericStrings)(validPayload, hubspotSchemaDiff.numericStrings);
    switch (hubspotSchemaDiff.match) {
        case types_1.SchemaMatch.FullMatch: {
            await (0, cache_functions_1.saveSchemaToCache)(hubspotSchema, subscriptionMetadata, statsContext);
            return await (0, event_completion_functions_1.sendEvent)(client, hubspotSchema.fullyQualifiedName, validPayload);
        }
        case types_1.SchemaMatch.PropertiesMissing: {
            if (syncMode === 'add') {
                throw new actions_core_1.IntegrationError(`The 'Sync Mode' setting is set to 'add' which is stopping Segment from creating a new properties on the Event Schema in the HubSpot`, 'HUBSPOT_SCHEMA_PROPERTIES_MISSING', 400);
            }
            const cacheableSchema = {
                ...schema,
                fullyQualifiedName: hubspotSchema.fullyQualifiedName,
                properties: {
                    ...hubspotSchema.properties,
                    ...hubspotSchemaDiff.missingProperties
                }
            };
            await (0, hubspot_event_schema_functions_1.updateHubspotSchema)(client, cacheableSchema.fullyQualifiedName, hubspotSchemaDiff);
            await (0, cache_functions_1.saveSchemaToCache)(cacheableSchema, subscriptionMetadata, statsContext);
            return await (0, event_completion_functions_1.sendEvent)(client, cacheableSchema.fullyQualifiedName, validPayload);
        }
        case types_1.SchemaMatch.NoMatch: {
            if (syncMode === 'update') {
                throw new actions_core_1.IntegrationError(`The 'Sync Mode' setting is set to 'update' which is stopping Segment from creating a new Custom Event Schema in the HubSpot`, 'HUBSPOT_SCHEMA_MISSING', 400);
            }
            const fullyQualifiedName = await (0, hubspot_event_schema_functions_1.createHubspotEventSchema)(client, schema);
            const cacheableSchema = { ...schema, fullyQualifiedName };
            await (0, cache_functions_1.saveSchemaToCache)(cacheableSchema, subscriptionMetadata, statsContext);
            return await (0, event_completion_functions_1.sendEvent)(client, cacheableSchema.fullyQualifiedName, validPayload);
        }
    }
};
exports.default = action;
//# sourceMappingURL=index.js.map