import { ValidationError } from "joi";
import { UseCaseError } from "../application";
import { IServerError, ServerError } from "../domain/errors";

export interface IInfrastructureError extends IServerError {}

export class InfrastructureError extends ServerError implements IInfrastructureError {
  public static readonly BAD_REQUEST = "BAD_REQUEST";
  public static readonly UNEXCEPTED_ERROR = "UNEXCEPTED_ERROR";
  public static readonly INVALID_INPUT_DATA = "INVALID_INPUT_DATA";
  public static readonly RESOURCE_NOT_READY = "RESOURCE_NOT_READY";
  public static readonly RESOURCE_NOT_FOUND_ERROR = "RESOURCE_NOT_FOUND_ERROR";
  public static readonly RESOURCE_ALREADY_REGISTERED = "RESOURCE_ALREADY_REGISTERED";

  public static create(
    code: string,
    message: string,
    error?: UseCaseError | ValidationError
  ): InfrastructureError {
    let payload = {};

    if (error) {
      if (error.name === "ValidationError") {
        //Joi error => error.details
        payload = (<ValidationError>error).details;
      } else {
        // UseCaseError
        const _error = <UseCaseError>error;
        const _payload = Array.isArray(_error.payload) ? _error.payload : [_error.payload];

        payload = _payload.map((item: Record<string, any>) => ({
          path: item.path,
          message: error.message,
        }));
      }
    }

    return new InfrastructureError(code, message, payload);
  }
}
