package ru.yandex.atom.utils.actor.messages

import ru.yandex.atom.error.{InternalProblem, UserProblem}

/**
 * @author avhaliullin
 */
sealed trait IFailureResponse {
  self: ResponseMessage[_] =>
}

trait IUserProblemResponse extends IFailureResponse {
  self: ResponseMessage[_] =>

  def problem: UserProblem
}

trait IInternalProblemResponse extends IFailureResponse {
  self: ResponseMessage[_] =>

  def problem: InternalProblem
}

trait IExceptionResponse extends IFailureResponse {
  self: ResponseMessage[_] =>
  def problem: Throwable
}

sealed trait IFailureMagnet

object IFailureMagnet {

  case class InternalProblemFailure(p: InternalProblem) extends IFailureMagnet

  case class UserProblemFailure(p: UserProblem) extends IFailureMagnet

  implicit def internalProblemIsIFailure(p: InternalProblem): IFailureMagnet = InternalProblemFailure(p)

  implicit def userProblemIsIFailure(p: UserProblem): IFailureMagnet = UserProblemFailure(p)

  implicit def exceptionIsIFailure(t: Throwable): IFailureMagnet = InternalProblemFailure(InternalProblem.throwable2InternalProblem(t))

  implicit def iFailureIsIFailure(r: IFailureResponse): IFailureMagnet = r match {
    case x: IUserProblemResponse => UserProblemFailure(x.problem)
    case x: IInternalProblemResponse => InternalProblemFailure(x.problem)
    case x: IExceptionResponse => exceptionIsIFailure(x.problem)
  }
}