"use strict";
/*
 * Copyright 2016 balena.io
 *
 * 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
 *
 *    http://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.HUMAN_FRIENDLY = void 0;
exports.getTitle = getTitle;
exports.getDescription = getDescription;
exports.createError = createError;
exports.createUserError = createUserError;
exports.toJSON = toJSON;
exports.fromJSON = fromJSON;
/**
 * @summary Human-friendly error messages
 */
exports.HUMAN_FRIENDLY = {
    ENOENT: {
        title: (error) => {
            return `No such file or directory: ${error.path}`;
        },
        description: () => "The file you're trying to access doesn't exist",
    },
    EPERM: {
        title: () => "You're not authorized to perform this operation",
        description: () => 'Please ensure you have necessary permissions for this task',
    },
    EACCES: {
        title: () => "You don't have access to this resource",
        description: () => 'Please ensure you have necessary permissions to access this resource',
    },
    ENOMEM: {
        title: () => 'Your system ran out of memory',
        description: () => 'Please make sure your system has enough available memory for this task',
    },
};
/**
 * @summary Get user friendly property from an error
 *
 * @example
 * const error = new Error('My error');
 * error.code = 'ENOMEM';
 *
 * const friendlyDescription = getUserFriendlyMessageProperty(error, 'description');
 *
 * if (friendlyDescription) {
 *   console.log(friendlyDescription);
 * }
 */
function getUserFriendlyMessageProperty(error, property) {
    if (typeof error.code !== 'string') {
        return undefined;
    }
    return exports.HUMAN_FRIENDLY[error.code]?.[property]?.(error);
}
function isBlank(s) {
    if (typeof s === 'number') {
        s = s.toString();
    }
    return (s ?? '').trim() === '';
}
/**
 * @summary Get the title of an error
 *
 * @description
 * Try to get as much information as possible about the error
 * rather than falling back to generic messages right away.
 */
function getTitle(error) {
    const codeTitle = getUserFriendlyMessageProperty(error, 'title');
    if (codeTitle !== undefined) {
        return codeTitle;
    }
    const message = error.message;
    if (!isBlank(message)) {
        return message;
    }
    const code = error.code;
    if (!isBlank(code)) {
        return `Error code: ${code}`;
    }
    return 'An error ocurred';
}
/**
 * @summary Get the description of an error
 */
function getDescription(error) {
    if (!isBlank(error.description)) {
        return error.description;
    }
    const codeDescription = getUserFriendlyMessageProperty(error, 'description');
    if (codeDescription !== undefined) {
        return codeDescription;
    }
    if (error.stack) {
        return error.stack;
    }
    return JSON.stringify(error, null, 2);
}
/**
 * @summary Create an error
 */
function createError(options) {
    if (isBlank(options.title)) {
        throw new Error(`Invalid error title: ${options.title}`);
    }
    const error = new Error(options.title);
    error.description = options.description;
    if (options.report === false) {
        error.report = false;
    }
    if (options.code !== undefined) {
        error.code = options.code;
    }
    return error;
}
/**
 * @summary Create a user error
 *
 * @description
 * User errors represent invalid states that the user
 * caused, that are not errors on the application itself.
 * Therefore, user errors don't get reported to analytics
 * and error reporting services.
 */
function createUserError(options) {
    return createError({
        title: options.title,
        description: options.description,
        report: false,
        code: options.code,
    });
}
/**
 * @summary Convert an Error object to a JSON object
 * @function
 * @public
 *
 * @param {Error} error - error object
 * @returns {Object} json error
 *
 * @example
 * const error = errors.toJSON(new Error('foo'))
 *
 * console.log(error.message);
 * > 'foo'
 */
function toJSON(error) {
    return {
        name: error.name,
        message: error.message,
        description: error.description,
        stack: error.stack,
        report: error.report,
        code: error.code,
        syscall: error.syscall,
        errno: error.errno,
        stdout: error.stdout,
        stderr: error.stderr,
        device: error.device,
    };
}
/**
 * @summary Convert a JSON object to an Error object
 */
function fromJSON(json) {
    return Object.assign(new Error(json.message), json);
}
