package docspell.common

import io.circe.{Decoder, Encoder}

sealed trait CollectiveState
object CollectiveState {
  val all = List(Active, ReadOnly, Closed, Blocked)

  /** A normal active collective */
  case object Active extends CollectiveState

  /** A collective may be readonly in cases it is implicitly closed
    * (e.g. no payment). Users can still see there data and
    * download, but have no write access. */
  case object ReadOnly extends CollectiveState

  /** A collective that has been explicitely closed. */
  case object Closed extends CollectiveState

  /** A collective blocked by a super user, usually some emergency
    * action. */
  case object Blocked extends CollectiveState


  def fromString(s: String): Either[String, CollectiveState] =
    s.toLowerCase match {
      case "active" => Right(Active)
      case "readonly" => Right(ReadOnly)
      case "closed" => Right(Closed)
      case "blocked" => Right(Blocked)
      case _ => Left(s"Unknown state: $s")
    }

  def unsafe(str: String): CollectiveState =
    fromString(str).fold(sys.error, identity)

  def asString(state: CollectiveState): String = state match {
    case Active => "active"
    case Blocked => "blocked"
    case Closed => "closed"
    case ReadOnly => "readonly"
  }



  implicit val collectiveStateEncoder: Encoder[CollectiveState] =
    Encoder.encodeString.contramap(CollectiveState.asString)

  implicit val collectiveStateDecoder: Decoder[CollectiveState] =
    Decoder.decodeString.emap(CollectiveState.fromString)

}