import MonitorType from "../../../Types/Monitor/MonitorType";
import Typeof from "../../../Types/Typeof";
import VMUtil from "../VM/VMAPI";
import logger from "../Logger";
/**
 * Utility for building template variable storage map and processing dynamic placeholders
 * shared between Incident and Alert auto-creation.
 */
export default class MonitorTemplateUtil {
    /**
     * Build a storage map of variables available for templating based on monitor type.
     */
    static buildTemplateStorageMap(data) {
        var _a, _b, _c, _d, _e, _f;
        let storageMap = {};
        try {
            if (data.monitorType === MonitorType.API ||
                data.monitorType === MonitorType.Website) {
                let responseBody = null;
                try {
                    responseBody = JSON.parse(data.dataToProcess
                        .responseBody || "{}");
                }
                catch (err) {
                    logger.error(err);
                    responseBody = data.dataToProcess
                        .responseBody;
                }
                if (typeof responseBody === Typeof.String &&
                    (responseBody === null || responseBody === void 0 ? void 0 : responseBody.toString()) === "") {
                    responseBody = {};
                }
                storageMap = {
                    responseBody: responseBody,
                    responseHeaders: data.dataToProcess
                        .responseHeaders,
                    responseStatusCode: data.dataToProcess
                        .responseCode,
                    responseTimeInMs: data.dataToProcess
                        .responseTimeInMs,
                    isOnline: data.dataToProcess.isOnline,
                };
            }
            if (data.monitorType === MonitorType.IncomingRequest) {
                storageMap = {
                    requestBody: data.dataToProcess
                        .requestBody,
                    requestHeaders: data.dataToProcess
                        .requestHeaders,
                    requestMethod: data.dataToProcess
                        .requestMethod,
                    incomingRequestReceivedAt: data.dataToProcess.incomingRequestReceivedAt,
                };
            }
            if (data.monitorType === MonitorType.Ping ||
                data.monitorType === MonitorType.IP ||
                data.monitorType === MonitorType.Port) {
                storageMap = {
                    isOnline: data.dataToProcess.isOnline,
                    responseTimeInMs: data.dataToProcess
                        .responseTimeInMs,
                    failureCause: data.dataToProcess
                        .failureCause,
                    isTimeout: data.dataToProcess.isTimeout,
                };
            }
            if (data.monitorType === MonitorType.SSLCertificate) {
                const sslResponse = data.dataToProcess.sslResponse;
                storageMap = {
                    isOnline: data.dataToProcess.isOnline,
                    isSelfSigned: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.isSelfSigned,
                    createdAt: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.createdAt,
                    expiresAt: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.expiresAt,
                    commonName: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.commonName,
                    organizationalUnit: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.organizationalUnit,
                    organization: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.organization,
                    locality: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.locality,
                    state: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.state,
                    country: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.country,
                    serialNumber: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.serialNumber,
                    fingerprint: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.fingerprint,
                    fingerprint256: sslResponse === null || sslResponse === void 0 ? void 0 : sslResponse.fingerprint256,
                    failureCause: data.dataToProcess
                        .failureCause,
                };
            }
            if (data.monitorType === MonitorType.Server) {
                const serverResponse = data.dataToProcess;
                const infraMetrics = serverResponse.basicInfrastructureMetrics;
                storageMap = {
                    hostname: serverResponse.hostname,
                    requestReceivedAt: serverResponse.requestReceivedAt,
                    failureCause: serverResponse.failureCause,
                };
                // Add CPU metrics if available
                if (infraMetrics === null || infraMetrics === void 0 ? void 0 : infraMetrics.cpuMetrics) {
                    storageMap["cpuUsagePercent"] = infraMetrics.cpuMetrics.percentUsed;
                    storageMap["cpuCores"] = infraMetrics.cpuMetrics.cores;
                }
                // Add memory metrics if available
                if (infraMetrics === null || infraMetrics === void 0 ? void 0 : infraMetrics.memoryMetrics) {
                    storageMap["memoryUsagePercent"] =
                        infraMetrics.memoryMetrics.percentUsed;
                    storageMap["memoryFreePercent"] =
                        infraMetrics.memoryMetrics.percentFree;
                    storageMap["memoryTotalBytes"] = infraMetrics.memoryMetrics.total;
                }
                // Add disk metrics if available
                if (infraMetrics === null || infraMetrics === void 0 ? void 0 : infraMetrics.diskMetrics) {
                    storageMap["diskMetrics"] = infraMetrics.diskMetrics.map((disk) => {
                        return {
                            diskPath: disk.diskPath,
                            usagePercent: disk.percentUsed,
                            freePercent: disk.percentFree,
                            totalBytes: disk.total,
                        };
                    });
                }
                // Add processes if available
                if (serverResponse.processes) {
                    storageMap["processes"] = serverResponse.processes.map((process) => {
                        return {
                            pid: process.pid,
                            name: process.name,
                            command: process.command,
                        };
                    });
                }
            }
            if (data.monitorType === MonitorType.CustomJavaScriptCode) {
                const customCodeResponse = data.dataToProcess.customCodeMonitorResponse;
                storageMap = {
                    executionTimeInMs: customCodeResponse === null || customCodeResponse === void 0 ? void 0 : customCodeResponse.executionTimeInMS,
                    result: customCodeResponse === null || customCodeResponse === void 0 ? void 0 : customCodeResponse.result,
                    scriptError: customCodeResponse === null || customCodeResponse === void 0 ? void 0 : customCodeResponse.scriptError,
                    logMessages: (customCodeResponse === null || customCodeResponse === void 0 ? void 0 : customCodeResponse.logMessages) || [],
                    failureCause: data.dataToProcess
                        .failureCause,
                };
            }
            if (data.monitorType === MonitorType.SyntheticMonitor) {
                const syntheticResponse = data.dataToProcess.syntheticMonitorResponse;
                /*
                 * Synthetic monitors run across multiple browser / screen-size combinations.
                 * Each run is exposed through the syntheticResponses array — use
                 * {{syntheticResponses[i].*}} or {{#each syntheticResponses}} in templates.
                 */
                storageMap = {
                    syntheticResponses: (syntheticResponse || []).map((response) => {
                        return {
                            executionTimeInMs: response.executionTimeInMS,
                            result: response.result,
                            scriptError: response.scriptError,
                            logMessages: response.logMessages || [],
                            screenshots: response.screenshots,
                            browserType: response.browserType,
                            screenSizeType: response.screenSizeType,
                        };
                    }),
                    failureCause: data.dataToProcess
                        .failureCause,
                };
            }
            if (data.monitorType === MonitorType.SNMP) {
                const snmpResponse = data.dataToProcess.snmpResponse;
                storageMap = {
                    isOnline: data.dataToProcess.isOnline,
                    responseTimeInMs: snmpResponse === null || snmpResponse === void 0 ? void 0 : snmpResponse.responseTimeInMs,
                    failureCause: snmpResponse === null || snmpResponse === void 0 ? void 0 : snmpResponse.failureCause,
                    isTimeout: snmpResponse === null || snmpResponse === void 0 ? void 0 : snmpResponse.isTimeout,
                };
                // Add OID responses as key-value pairs
                if (snmpResponse === null || snmpResponse === void 0 ? void 0 : snmpResponse.oidResponses) {
                    storageMap["oidResponses"] = snmpResponse.oidResponses.map((oidResponse) => {
                        return {
                            oid: oidResponse.oid,
                            name: oidResponse.name,
                            value: oidResponse.value,
                            type: oidResponse.type,
                        };
                    });
                    // Also add OIDs by name for easier templating
                    for (const oidResponse of snmpResponse.oidResponses) {
                        if (oidResponse.name) {
                            storageMap[oidResponse.name] = oidResponse.value;
                        }
                    }
                }
            }
            if (data.monitorType === MonitorType.DNS) {
                const dnsResponse = data.dataToProcess.dnsResponse;
                storageMap = {
                    isOnline: data.dataToProcess.isOnline,
                    responseTimeInMs: dnsResponse === null || dnsResponse === void 0 ? void 0 : dnsResponse.responseTimeInMs,
                    failureCause: dnsResponse === null || dnsResponse === void 0 ? void 0 : dnsResponse.failureCause,
                    isTimeout: dnsResponse === null || dnsResponse === void 0 ? void 0 : dnsResponse.isTimeout,
                    isDnssecValid: dnsResponse === null || dnsResponse === void 0 ? void 0 : dnsResponse.isDnssecValid,
                };
                // Add DNS records
                if (dnsResponse === null || dnsResponse === void 0 ? void 0 : dnsResponse.records) {
                    storageMap["records"] = dnsResponse.records.map((record) => {
                        return {
                            type: record.type,
                            value: record.value,
                            ttl: record.ttl,
                        };
                    });
                    // Add record values as a flat array for easier templating
                    storageMap["recordValues"] = dnsResponse.records.map((record) => {
                        return record.value;
                    });
                }
            }
            if (data.monitorType === MonitorType.Domain) {
                const domainResponse = data.dataToProcess.domainResponse;
                storageMap = {
                    isOnline: data.dataToProcess.isOnline,
                    responseTimeInMs: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.responseTimeInMs,
                    failureCause: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.failureCause,
                    domainName: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.domainName,
                    registrar: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.registrar,
                    createdDate: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.createdDate,
                    updatedDate: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.updatedDate,
                    expiresDate: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.expiresDate,
                    nameServers: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.nameServers,
                    domainStatus: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.domainStatus,
                    dnssec: domainResponse === null || domainResponse === void 0 ? void 0 : domainResponse.dnssec,
                };
            }
            if (data.monitorType === MonitorType.DNSSEC) {
                const dnssecResponse = data.dataToProcess.dnssecResponse;
                storageMap = {
                    isOnline: data.dataToProcess.isOnline,
                    responseTimeInMs: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.responseTimeInMs,
                    failureCause: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.failureCause,
                    domainName: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.domainName,
                    isZoneSigned: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.isZoneSigned,
                    isParentDsPresent: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.isParentDsPresent,
                    isChainValid: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.isChainValid,
                    resolverConsensusAd: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.resolverConsensusAd,
                    isNameserverConsistent: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.isNameserverConsistent,
                    earliestSignatureExpiration: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.earliestSignatureExpiration,
                    daysUntilSignatureExpiry: dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.daysUntilSignatureExpiry,
                    dnskeyCount: (_a = dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.dnskeys) === null || _a === void 0 ? void 0 : _a.length,
                    dsRecordCount: (_b = dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.parentDsRecords) === null || _b === void 0 ? void 0 : _b.length,
                    rrsigCount: (_c = dnssecResponse === null || dnssecResponse === void 0 ? void 0 : dnssecResponse.rrsigs) === null || _c === void 0 ? void 0 : _c.length,
                };
            }
            if (data.monitorType === MonitorType.Metrics ||
                data.monitorType === MonitorType.Kubernetes ||
                data.monitorType === MonitorType.Docker) {
                const metricResponse = data.dataToProcess;
                const queryConfigs = ((_d = metricResponse.metricViewConfig) === null || _d === void 0 ? void 0 : _d.queryConfigs) || [];
                const firstQuery = queryConfigs[0];
                const metricName = (_f = (_e = firstQuery === null || firstQuery === void 0 ? void 0 : firstQuery.metricQueryData) === null || _e === void 0 ? void 0 : _e.filterData) === null || _f === void 0 ? void 0 : _f.metricName;
                storageMap = {
                    metricName: metricName || "",
                };
            }
            if (data.monitorType === MonitorType.ExternalStatusPage) {
                const externalStatusPageResponse = data.dataToProcess
                    .externalStatusPageResponse;
                storageMap = {
                    isOnline: data.dataToProcess.isOnline,
                    responseTimeInMs: externalStatusPageResponse === null || externalStatusPageResponse === void 0 ? void 0 : externalStatusPageResponse.responseTimeInMs,
                    failureCause: externalStatusPageResponse === null || externalStatusPageResponse === void 0 ? void 0 : externalStatusPageResponse.failureCause,
                    overallStatus: externalStatusPageResponse === null || externalStatusPageResponse === void 0 ? void 0 : externalStatusPageResponse.overallStatus,
                    activeIncidentCount: externalStatusPageResponse === null || externalStatusPageResponse === void 0 ? void 0 : externalStatusPageResponse.activeIncidentCount,
                };
                // Add component statuses
                if (externalStatusPageResponse === null || externalStatusPageResponse === void 0 ? void 0 : externalStatusPageResponse.componentStatuses) {
                    storageMap["componentStatuses"] =
                        externalStatusPageResponse.componentStatuses.map((component) => {
                            return {
                                name: component.name,
                                status: component.status,
                                description: component.description,
                            };
                        });
                }
            }
        }
        catch (err) {
            logger.error(err);
        }
        /*
         * Fold series labels onto the storage map so templates like
         * `{{host.name}}` or `{{resource.k8s.container.name}}` resolve at
         * render time. The template engine walks dotted paths as nested
         * property access (`host` → `.name`), so for each dotted label
         * key we build up a nested object rather than storing the flat
         * key. Also expose the full label map under `seriesLabels` for
         * iteration-style templates.
         */
        if (data.seriesLabels && Object.keys(data.seriesLabels).length > 0) {
            for (const key of Object.keys(data.seriesLabels)) {
                const value = data.seriesLabels[key];
                if (value === undefined || value === null) {
                    continue;
                }
                const parts = key.split(".");
                let cursor = storageMap;
                for (let i = 0; i < parts.length - 1; i++) {
                    const part = parts[i];
                    const existing = cursor[part];
                    if (!existing ||
                        typeof existing !== "object" ||
                        Array.isArray(existing)) {
                        cursor[part] = {};
                    }
                    cursor = cursor[part];
                }
                cursor[parts[parts.length - 1]] = value;
            }
            storageMap["seriesLabels"] = data.seriesLabels;
        }
        /*
         * Monitor identity fields. Always exposed (when a monitor is provided),
         * independent of monitorType, so templates like `{{monitorName}}` work
         * uniformly across Server/VM, Probe, Synthetic, Metric monitors, etc.
         */
        if (data.monitor) {
            if (data.monitor.name) {
                storageMap["monitorName"] = data.monitor.name;
            }
            if (data.monitor.id) {
                storageMap["monitorId"] = data.monitor.id.toString();
            }
            if (data.monitor.description) {
                storageMap["monitorDescription"] = data.monitor.description;
            }
            if (data.monitor.slug) {
                storageMap["monitorSlug"] = data.monitor.slug;
            }
            if (data.monitor.monitorType) {
                storageMap["monitorType"] = data.monitor.monitorType;
            }
        }
        logger.debug(`Storage Map: ${JSON.stringify(storageMap, null, 2)}`);
        return storageMap;
    }
    /**
     * Replace {{var}} placeholders in the given string with values from the storage map.
     */
    static processTemplateString(data) {
        try {
            const { value, storageMap } = data;
            if (!value) {
                return "";
            }
            let replaced = VMUtil.replaceValueInPlace(storageMap, value, false);
            replaced =
                replaced !== undefined && replaced !== null ? `${replaced}` : "";
            logger.debug(`Original Value: ${data.value}`);
            logger.debug(`Replaced Value: ${replaced}`);
            return replaced;
        }
        catch (err) {
            logger.error(err);
            return data.value || "";
        }
    }
}
//# sourceMappingURL=MonitorTemplateUtil.js.map