package ru.yandex.atom.service

import ru.yandex.atom.utils.actor.messages._
import akka.actor.ActorRef
import ru.yandex.atom.error.{InternalProblem, UserProblem}
import ru.yandex.atom.data.ReqID
import spray.http.RemoteAddress

/**
 * @author avhaliullin
 */
trait APIKeysActorComponent {

  def apiKeysActor: ActorRef

  sealed trait APIKeysRequest extends AbstractMessage

  object APIKeysRequest {

    case class CheckKey(id: ReqID, key: String, ip: RemoteAddress) extends APIKeysRequest

    case class CreateKey(id: ReqID, uid: Long) extends APIKeysRequest

  }

  sealed trait APIKeysResponse extends ResponseMessage[APIKeysRequest]

  object APIKeysResponse {

    case class KeyChecked(request: APIKeysRequest.CheckKey, uid: Option[Long]) extends APIKeysResponse with SetReqType[APIKeysRequest.CheckKey]

    case class KeyCreated(request: APIKeysRequest.CreateKey, key: String) extends APIKeysResponse with SetReqType[APIKeysRequest.CreateKey]

    sealed trait FailureResponse extends APIKeysResponse with SetReqType[APIKeysRequest] {
      self: IFailureResponse =>
    }

    object FailureResponse {
      def apply(req: APIKeysRequest, cause: IFailureMagnet): FailureResponse = cause match {
        case IFailureMagnet.InternalProblemFailure(problem) => InternalProblemResponse(req, problem)
        case IFailureMagnet.UserProblemFailure(problem) => UserProblemResponse(req, problem)
      }
    }

    case class UserProblemResponse(request: APIKeysRequest, problem: UserProblem) extends FailureResponse with IUserProblemResponse

    case class InternalProblemResponse(request: APIKeysRequest, problem: InternalProblem) extends FailureResponse with IInternalProblemResponse

  }


}
