"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const actions_core_1 = require("@segment/actions-core");
const common_fields_1 = require("./common-fields");
const client_1 = require("./client");
const types_1 = require("./types");
const dynamic_field_functions_1 = require("./functions/dynamic-field-functions");
const cache_functions_1 = require("./functions/cache-functions");
const validation_functions_1 = require("./functions/validation-functions");
const schema_functions_1 = require("./functions/schema-functions");
const hubspot_record_functions_1 = require("./functions/hubspot-record-functions");
const hubspot_list_functions_1 = require("./functions/hubspot-list-functions");
const hubspot_association_functions_1 = require("./functions/hubspot-association-functions");
const hubspot_properties_functions_1 = require("./functions/hubspot-properties-functions");
const action = {
    title: 'Custom Object V2',
    description: 'Add, create or update records of any Object type to HubSpot, and optionally assocate that record with other records of any Object type.',
    syncMode: {
        description: 'Specify how Segment should update Records in Hubspot',
        label: 'Sync Mode',
        default: 'update',
        choices: [
            { label: 'Create new records, and update existing records', value: 'upsert' },
            { label: 'Create new records, but do not update existing records', value: 'add' },
            { label: 'Update existing records, but do not create new records', value: 'update' }
        ]
    },
    fields: {
        ...common_fields_1.commonFields
    },
    dynamicFields: dynamic_field_functions_1.dynamicFields,
    perform: async (request, { payload, syncMode, subscriptionMetadata, statsContext, features }) => {
        statsContext?.tags?.push('action:custom_object');
        return await send(request, [payload], syncMode, subscriptionMetadata, statsContext, features);
    },
    performBatch: async (request, data) => {
        const requestData = data;
        const { payload, syncMode, subscriptionMetadata, statsContext, rawData } = requestData;
        const { features } = data;
        statsContext?.tags?.push('action:custom_object_batch');
        return await send(request, payload, syncMode, subscriptionMetadata, statsContext, features, rawData);
    }
};
const send = async (request, payloads, syncMode, subscriptionMetadata, statsContext, features, rawData) => {
    if (syncMode === 'upsert' || syncMode === 'update') {
        payloads = (0, validation_functions_1.ensureValidTimestamps)(payloads, rawData);
        payloads = (0, validation_functions_1.mergeAndDeduplicateById)(payloads, statsContext);
    }
    const { object_details: { object_type: objectType, property_group: propertyGroup }, association_sync_mode: associationSyncMode, list_details } = payloads[0];
    const flag = features?.['actions-hubspot-lists-association-support'] ?? false;
    let listName = undefined;
    const client = new client_1.Client(request, objectType);
    const validPayloads = (0, validation_functions_1.validate)(payloads, flag);
    if (flag) {
        listName = (0, hubspot_list_functions_1.getListName)(payloads[0]);
    }
    const schema = (0, schema_functions_1.objectSchema)(validPayloads, objectType);
    const cachedSchema = (0, cache_functions_1.getSchemaFromCache)(schema.object_details.object_type, subscriptionMetadata, statsContext);
    statsContext?.statsClient?.incr(`cache.get.${cachedSchema === undefined ? 'miss' : 'hit'}`, 1, statsContext?.tags);
    const cacheSchemaDiff = (0, schema_functions_1.compareSchemas)(schema, cachedSchema, statsContext);
    statsContext?.statsClient?.incr(`cache.diff.${cacheSchemaDiff.match}`, 1, statsContext?.tags);
    if (cacheSchemaDiff.match === types_1.SchemaMatch.PropertiesMissing || cacheSchemaDiff.match === types_1.SchemaMatch.NoMatch) {
        const hubspotSchema = await (0, hubspot_properties_functions_1.getSchemaFromHubspot)(client, schema);
        const hubspotSchemaDiff = (0, schema_functions_1.compareSchemas)(schema, hubspotSchema, statsContext);
        switch (hubspotSchemaDiff.match) {
            case types_1.SchemaMatch.FullMatch: {
                await (0, cache_functions_1.saveSchemaToCache)(schema, subscriptionMetadata, statsContext);
                break;
            }
            case types_1.SchemaMatch.PropertiesMissing: {
                await (0, hubspot_properties_functions_1.createProperties)(client, hubspotSchemaDiff, propertyGroup);
                await (0, cache_functions_1.saveSchemaToCache)(schema, subscriptionMetadata, statsContext);
                break;
            }
            case types_1.SchemaMatch.NoMatch: {
                throw new actions_core_1.IntegrationError('Object Type missing', 'Object Type missing', 400);
            }
        }
    }
    let cachableList = undefined;
    if (flag) {
        const shouldCreateList = list_details?.should_create_list ?? false;
        cachableList = await (0, hubspot_list_functions_1.ensureList)(client, objectType, listName, shouldCreateList, subscriptionMetadata, statsContext);
    }
    const fromRecordPayloads = await (0, hubspot_record_functions_1.sendFromRecords)(client, validPayloads, objectType, syncMode);
    const associationPayloads = (0, validation_functions_1.deDuplicateAssociations)((0, hubspot_association_functions_1.createAssociationPayloads)(fromRecordPayloads, 'associations'));
    const associatedRecords = await (0, hubspot_association_functions_1.sendAssociatedRecords)(client, associationPayloads, associationSyncMode);
    await (0, hubspot_association_functions_1.sendAssociations)(client, associatedRecords, 'create');
    if (flag) {
        const dissociationPayloads = (0, hubspot_association_functions_1.createAssociationPayloads)(fromRecordPayloads, 'dissociations');
        const dissociatedRecords = await (0, hubspot_association_functions_1.sendAssociatedRecords)(client, dissociationPayloads, types_1.AssociationSyncMode.Read);
        await (0, hubspot_association_functions_1.sendAssociations)(client, dissociatedRecords, 'archive');
        if (cachableList) {
            await (0, hubspot_list_functions_1.sendLists)(client, cachableList, fromRecordPayloads);
        }
    }
    return;
};
exports.default = action;
//# sourceMappingURL=index.js.map