// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { Constants } from "../common/constants.js";
import { StatusCodes, SubStatusCodes } from "../common/statusCodes.js";
import { ErrorResponse } from "../index.js";
import { isSuccessStatusCode } from "../utils/batch.js";
/**
 * Represents a batch response for bulk request.
 * @hidden
 */
export class BulkResponse {
    statusCode;
    subStatusCode;
    headers;
    operations;
    results = [];
    diagnostics;
    constructor(statusCode, subStatusCode, headers, operations) {
        this.statusCode = statusCode;
        this.subStatusCode = subStatusCode;
        this.headers = headers;
        this.operations = operations;
    }
    /**
     * Generate empty response object
     */
    static createEmptyResponse(operations, statusCode, subStatusCode, headers) {
        const bulkResponse = new BulkResponse(statusCode, subStatusCode, headers, operations);
        bulkResponse.createAndPopulateResults(operations, 0, new ErrorResponse());
        return bulkResponse;
    }
    /**
     * static method to create BulkResponse from Response object
     */
    static fromResponseMessage(responseMessage, operations) {
        // Create and populate the response object
        let bulkResponse = this.populateFromResponse(responseMessage, operations);
        if (!bulkResponse.results || bulkResponse.results.length !== operations.length) {
            // Server should be guaranteeing number of results equal to operations when
            // batch request is successful - so fail as InternalServerError if this is not the case.
            if (isSuccessStatusCode(responseMessage.code)) {
                bulkResponse = new BulkResponse(StatusCodes.InternalServerError, SubStatusCodes.Unknown, responseMessage.headers, operations);
            }
            // When the overall response status code is TooManyRequests, propagate the RetryAfter into the individual operations.
            let retryAfterMilliseconds = 0;
            if (responseMessage.code === StatusCodes.TooManyRequests) {
                const retryAfter = responseMessage.headers?.[Constants.HttpHeaders.RetryAfterInMs];
                retryAfterMilliseconds = !retryAfter || isNaN(Number(retryAfter)) ? 0 : Number(retryAfter);
            }
            bulkResponse.createAndPopulateResults(operations, retryAfterMilliseconds, responseMessage);
        }
        return bulkResponse;
    }
    static populateFromResponse(responseMessage, operations) {
        const results = [];
        if (responseMessage.result) {
            for (let i = 0; i < operations.length; i++) {
                const itemResponse = responseMessage.result[i];
                if (isSuccessStatusCode(itemResponse?.statusCode)) {
                    const result = {
                        statusCode: itemResponse?.statusCode,
                        eTag: itemResponse?.eTag,
                        activityId: responseMessage.headers?.[Constants.HttpHeaders.ActivityId],
                        sessionToken: responseMessage.headers?.[Constants.HttpHeaders.SessionToken],
                        requestCharge: itemResponse?.requestCharge,
                        resourceBody: itemResponse?.resourceBody,
                        // diagnostics will be filled in Batcher dispatch to capture the complete diagnostics(e.g. decryption)
                        diagnostics: null,
                        headers: responseMessage.headers,
                    };
                    results.push(result);
                }
                else {
                    const error = new ErrorResponse();
                    error.code = itemResponse?.statusCode;
                    error.substatus = itemResponse?.subStatusCode;
                    error.message = itemResponse?.message;
                    error.requestCharge = itemResponse?.requestCharge;
                    error.body = itemResponse?.resourceBody;
                    error.headers = responseMessage.headers;
                    error.activityId = responseMessage.headers?.[Constants.HttpHeaders.ActivityId];
                    error.retryAfterInMs = itemResponse?.retryAfterMilliseconds;
                    error.diagnostics = responseMessage.diagnostics;
                    results.push(error);
                }
            }
        }
        let statusCode = responseMessage.code;
        let subStatusCode = responseMessage.substatus;
        if (responseMessage.code === StatusCodes.MultiStatus) {
            for (const result of results) {
                if (result instanceof ErrorResponse &&
                    result.statusCode !== StatusCodes.FailedDependency &&
                    result.statusCode >= StatusCodes.BadRequest) {
                    statusCode = typeof result.code === "number" ? result.code : Number(result.code);
                    subStatusCode = result.substatus;
                    break;
                }
            }
        }
        const bulkResponse = new BulkResponse(statusCode, subStatusCode, responseMessage.headers, operations);
        bulkResponse.results = results;
        return bulkResponse;
    }
    createAndPopulateResults(operations, retryAfterInMs, error) {
        this.results = operations.map(() => {
            const errorResponse = new ErrorResponse();
            errorResponse.message = error.message;
            errorResponse.code = this.statusCode;
            errorResponse.substatus = this.subStatusCode;
            errorResponse.retryAfterInMs = retryAfterInMs;
            errorResponse.activityId = this.headers?.[Constants.HttpHeaders.ActivityId];
            errorResponse.body = error.body;
            errorResponse.diagnostics = error.diagnostics;
            errorResponse.headers = this.headers;
            errorResponse.requestCharge = error.requestCharge;
            return errorResponse;
        });
    }
}
//# sourceMappingURL=BulkResponse.js.map