import { Exception } from '../exceptions/exception.js';
export const E_INVALID_JSON = 'Invalid JSON response.';
export const E_RESPONSE_NO_VALUE = 'The response has no value.';
export const E_RESPONSE_STATUS = 'Invalid response status: ';
export const E_RESPONSE_UNKNOWN = 'Unknown response from the server.';
export const E_RESPONSE_LOCATION = 'The response has no "location" header.';
export class SdkBase {
    sdk;
    constructor(sdk) {
        this.sdk = sdk;
    }
    logInvalidResponse(response) {
        if (this.sdk.silent) {
            return;
        }
        if (response.body) {
            try {
                const data = JSON.parse(response.body);
                if (data.message) {
                    console.warn(`[Store message]: ${data.message}`);
                }
            }
            catch {
                // .
            }
        }
    }
    /**
     * Throws unified message for a common error status codes.
     * It handles 404, 403, and 401 status codes.
     */
    inspectCommonStatusCodes(response) {
        const { status, body } = response;
        if (status === 404) {
            const e = this.createApiError('Not found', body);
            if (e.status !== 404) {
                e.setStatus(404);
            }
            if (e.code !== 'E_NOT_FOUND') {
                e.setCode('E_NOT_FOUND');
            }
            throw e;
        }
        if (status === 403) {
            const e = this.createApiError('You have no access to this resource', body);
            if (e.status !== 403) {
                e.setStatus(403);
            }
            if (e.code !== 'E_FORBIDDEN') {
                e.setCode('E_FORBIDDEN');
            }
            throw e;
        }
        if (status === 401) {
            const e = this.createApiError('Not authorized', body);
            if (e.status !== 401) {
                e.setStatus(401);
            }
            if (e.code !== 'E_UNAUTHORIZED') {
                e.setCode('E_UNAUTHORIZED');
            }
            throw e;
        }
    }
    /**
     * Creates an Exception from the response body.
     * It reads the error details from the body.
     *
     * @param defaultMessage The default message to use if the body does not contain a message.
     * @param body The message returned by the store.
     * @returns The Exception or undefined when not an error.
     */
    createApiError(defaultMessage, body) {
        if (!body) {
            return new Exception(defaultMessage);
        }
        let data;
        try {
            data = JSON.parse(body);
        }
        catch {
            return new Exception(defaultMessage);
        }
        if (!data || typeof data !== 'object' || !data.message) {
            return new Exception(defaultMessage);
        }
        return Exception.fromRawException(data, defaultMessage);
    }
    /**
     * A generic (common) method to batch-delete object from the store.
     *
     * @param url The URL object to make the request.
     * @param keys The list of keys to delete
     * @param request Optional request options.
     * @returns THe list of context delete records.
     */
    async genericBatchDelete(url, keys, request = {}) {
        const { token } = request;
        const result = await this.sdk.http.post(url.toString(), { token, body: JSON.stringify(keys) });
        this.inspectCommonStatusCodes(result);
        const E_PREFIX = 'Unable to delete in batch. ';
        if (result.status !== 200) {
            this.logInvalidResponse(result);
            throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body);
        }
        if (!result.body) {
            throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status });
        }
        let data;
        try {
            data = JSON.parse(result.body);
        }
        catch {
            throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status });
        }
        if (!Array.isArray(data.items)) {
            throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status });
        }
        return data;
    }
    /**
     * Generic (common) function to delete an entity in the store.
     *
     * @param url The URL to make the DELETE request to.
     * @param request Optional request options.
     */
    async genericDelete(url, request = {}) {
        const { token } = request;
        const result = await this.sdk.http.delete(url.toString(), { token });
        this.inspectCommonStatusCodes(result);
        const E_PREFIX = 'Unable to delete the object. ';
        if (result.status !== 204) {
            this.logInvalidResponse(result);
            throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body);
        }
    }
    async genericList(url, options, request = {}) {
        const { token } = request;
        this.sdk.appendListOptions(url, options);
        const result = await this.sdk.http.get(url.toString(), { token });
        this.inspectCommonStatusCodes(result);
        const E_PREFIX = 'Unable to list revisions for a file. ';
        if (result.status !== 200) {
            this.logInvalidResponse(result);
            throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body);
        }
        if (!result.body) {
            throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status });
        }
        let data;
        try {
            data = JSON.parse(result.body);
        }
        catch {
            throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status });
        }
        if (!Array.isArray(data.items)) {
            throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status });
        }
        return data;
    }
    readResponseBody(response, errorPrefix) {
        if (response.status !== 200) {
            this.logInvalidResponse(response);
            throw this.createApiError(`${errorPrefix}${E_RESPONSE_STATUS}${response.status}`, response.body);
        }
        if (!response.body) {
            throw new Exception(`${errorPrefix}${E_RESPONSE_NO_VALUE}`, {
                code: 'E_RESPONSE_NO_VALUE',
                status: response.status,
            });
        }
        return response.body;
    }
    readResponseJSON(response, errorPrefix) {
        const body = this.readResponseBody(response, errorPrefix);
        let data;
        try {
            data = JSON.parse(body);
        }
        catch {
            throw new Exception(`${errorPrefix}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: response.status });
        }
        return data;
    }
}
//# sourceMappingURL=SdkBase.js.map