/**
 *  @module     @magic.batua/error
 *  @overview   Defines the `Error` handling interfaces used throughout the Magic Batua
 *              codebase.
 *  
 *  @author     Animesh Mishra <hello@animesh.ltd>
 *  @copyright  © 2018 Animesh Ltd. All Rights Reserved.
 */

import * as Express      from "express"
import { Code }          from "./Source/Code"
import { ClientError }   from "./Source/ClientError"
import { ExternalError } from "./Source/ExternalError"

/**
 *  @exports Error
 */
export var description = "Exports error handling functionalities"

/**
 *  All the errors thrown by the application code, in any of the modules,
 *  are routed through this method.
 *  
 *  Upon receiving an `error`, the method first runs an identity check.
 * 
 *  - If the `error` is of type `ClientError`, it sends an error response with
 *    one of the 4xx status codes.
 *  - If the `error` is of type `ExternalError`, it sends an error response with
 *    a `424 Failed Dependency` status code.
 *  - If the `error` is of any other type, it's assumed to an internal server 
 *    error and a `500 Internal Server Error` response is sent.
 * 
 *  
 *  Regardless of the error type, each response includes a detailed description,
 *  help message and debugging information in the response body.
 * 
 *  @param { Error } error  The error thrown 
 *  @param { Express.Response } response The response object that will be used to
 *                                       communicate the error back to the client 
 */
export function Handle(error: Error, response: Express.Response) {
    switch(error.constructor) {
        case ClientError:
            let clientError = error as ClientError
            response.status(clientError.code).json(clientError.Export())
            break
        case ExternalError:
            let externalError = error as ExternalError
            response.status(externalError.code).json(externalError.Export())
            break
        default:
            response.status(Code.Internal).send(error.message)
    }
}

// Exports
export { ExternalError }
export { ClientError }
export { Code }