"use strict";
/*
 * Copyright The OpenTelemetry Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.OTLPGRPCExporterNodeBase = void 0;
const api_1 = require("@opentelemetry/api");
const otlp_exporter_base_1 = require("@opentelemetry/otlp-exporter-base");
const grpc_exporter_transport_1 = require("./grpc-exporter-transport");
const otlp_grpc_configuration_1 = require("./configuration/otlp-grpc-configuration");
const otlp_grpc_env_configuration_1 = require("./configuration/otlp-grpc-env-configuration");
/**
 * OTLP Exporter abstract base class
 */
class OTLPGRPCExporterNodeBase extends otlp_exporter_base_1.OTLPExporterBase {
    constructor(config = {}, serializer, grpcName, grpcPath, signalIdentifier) {
        super(config);
        // keep credentials locally in case user updates the reference on the config object
        const userProvidedCredentials = config.credentials;
        const actualConfig = (0, otlp_grpc_configuration_1.mergeOtlpGrpcConfigurationWithDefaults)({
            url: config.url,
            metadata: () => {
                var _a;
                // metadata resolution strategy is merge, so we can return empty here, and it will not override the rest of the settings.
                return (_a = config.metadata) !== null && _a !== void 0 ? _a : (0, grpc_exporter_transport_1.createEmptyMetadata)();
            },
            compression: config.compression,
            timeoutMillis: config.timeoutMillis,
            concurrencyLimit: config.concurrencyLimit,
            credentials: userProvidedCredentials != null
                ? () => userProvidedCredentials
                : undefined,
        }, (0, otlp_grpc_env_configuration_1.getOtlpGrpcConfigurationFromEnv)(signalIdentifier), (0, otlp_grpc_configuration_1.getOtlpGrpcDefaultConfiguration)());
        this._serializer = serializer;
        this._timeoutMillis = actualConfig.timeoutMillis;
        this._concurrencyLimit = actualConfig.concurrencyLimit;
        if (config.headers) {
            api_1.diag.warn('Headers cannot be set when using grpc');
        }
        this._transport = new grpc_exporter_transport_1.GrpcExporterTransport({
            address: actualConfig.url,
            compression: actualConfig.compression,
            credentials: actualConfig.credentials,
            grpcName: grpcName,
            grpcPath: grpcPath,
            metadata: actualConfig.metadata,
        });
    }
    onShutdown() {
        this._transport.shutdown();
    }
    send(objects, onSuccess, onError) {
        if (this._shutdownOnce.isCalled) {
            api_1.diag.debug('Shutdown already started. Cannot send objects');
            return;
        }
        const data = this._serializer.serializeRequest(objects);
        if (data == null) {
            onError(new Error('Could not serialize message'));
            return;
        }
        const promise = this._transport
            .send(data, this._timeoutMillis)
            .then(response => {
            if (response.status === 'success') {
                onSuccess();
            }
            else if (response.status === 'failure' && response.error) {
                onError(response.error);
            }
            else if (response.status === 'retryable') {
                onError(new otlp_exporter_base_1.OTLPExporterError('Export failed with retryable status'));
            }
            else {
                onError(new otlp_exporter_base_1.OTLPExporterError('Export failed with unknown error'));
            }
        }, onError);
        this._sendingPromises.push(promise);
        const popPromise = () => {
            const index = this._sendingPromises.indexOf(promise);
            this._sendingPromises.splice(index, 1);
        };
        promise.then(popPromise, popPromise);
    }
}
exports.OTLPGRPCExporterNodeBase = OTLPGRPCExporterNodeBase;
//# sourceMappingURL=OTLPGRPCExporterNodeBase.js.map