<commit_before>package com.monsanto.arch.cloudformation.model.resource

import com.monsanto.arch.cloudformation.model.{ConditionRef, Token}
import spray.json._

/**
 * Created by bkrodg on 3/30/15.
 */
case class `AWS::S3::Bucket`(name:                      String,
                             BucketName:                Option[Token[String]],
                             AccessControl:             Option[S3AccessControl] = None,
                             CorsConfiguration:         Option[S3CorsRules] = None,
                             LifecycleConfiguration:    Option[S3LifecycleConfigurationRules] = None,
                             LoggingConfiguration:      Option[S3LoggingConfiguration] = None,
                             NotificationConfiguration: Option[TopicConfigurations] = None,
                             VersioningConfiguration:   Option[S3VersioningConfiguration] = None,
                             WebsiteConfiguration:      Option[S3WebsiteConfiguration] = None,
                             Tags:                      Option[Seq[AmazonTag]] = None,
                             override val Condition:    Option[ConditionRef] = None) extends Resource[`AWS::S3::Bucket`] {
  def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}
object `AWS::S3::Bucket` extends DefaultJsonProtocol {
  implicit val format: JsonFormat[`AWS::S3::Bucket`] = jsonFormat11(`AWS::S3::Bucket`.apply)
}

case class S3CorsRules(CorsRules: Seq[S3CorsRule])
object S3CorsRules extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3CorsRules] = jsonFormat1(S3CorsRules.apply)
}

case class S3CorsRule(AllowedMethods: Seq[String],
                      AllowedOrigins: Seq[String],
                      AllowedHeaders: Option[Seq[String]],
                      ExposedHeaders: Option[Seq[String]],
                      Id:             Option[String],
                      MaxAge:         Option[Int])
object S3CorsRule extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3CorsRule] = jsonFormat6(S3CorsRule.apply)
}

case class S3LifecycleConfigurationRules(Rules: Seq[S3LifecycleConfigurationRule])
object S3LifecycleConfigurationRules extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3LifecycleConfigurationRules] = jsonFormat1(S3LifecycleConfigurationRules.apply)
}

case class S3LifecycleConfigurationRule(Status: S3LifecycleConfigurationRuleStatus,
                                        ExpirationDate: Option[String],
                                        ExpirationInDays: Option[Int],
                                        Id: Option[String],
                                        Prefix: Option[String],
                                        Transition: Option[S3LifecycleTransition])
object S3LifecycleConfigurationRule extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3LifecycleConfigurationRule] = jsonFormat6(S3LifecycleConfigurationRule.apply)
}

case class S3LifecycleTransition(StorageClass: String,
                                 TransitionDate: Option[String],
                                 TransitionInDays: Option[Int])
object S3LifecycleTransition extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3LifecycleTransition] = jsonFormat3(S3LifecycleTransition.apply)
}

sealed trait S3LifecycleConfigurationRuleStatus
object S3LifecycleConfigurationRuleStatus extends DefaultJsonProtocol {
  case object Enabled extends S3LifecycleConfigurationRuleStatus
  case object Disabled extends S3LifecycleConfigurationRuleStatus

  implicit val format: JsonFormat[S3LifecycleConfigurationRuleStatus] = new JsonFormat[S3LifecycleConfigurationRuleStatus] {
    override def write(obj: S3LifecycleConfigurationRuleStatus)= JsString(obj.toString)
    override def read(json: JsValue): S3LifecycleConfigurationRuleStatus = {
      json.toString match {
        case "Enabled"  => Enabled
        case "Disabled" => Disabled
      }
    }
  }
}

sealed trait S3AccessControl
object S3AccessControl extends DefaultJsonProtocol {
  case object Private                   extends S3AccessControl
  case object PublicRead                extends S3AccessControl
  case object PublicReadWrite           extends S3AccessControl
  case object AuthenticatedRead         extends S3AccessControl
  case object LogDeliveryWrite          extends S3AccessControl
  case object BucketOwnerRead           extends S3AccessControl
  case object BucketOwnerFullControl    extends S3AccessControl

  implicit val format: JsonFormat[S3AccessControl] = new JsonFormat[S3AccessControl] {
    override def write(obj: S3AccessControl) = JsString(obj.toString)
    override def read(json: JsValue): S3AccessControl = {
      json.toString match {
        case "Private"                    => Private
        case "PublicRead"                 => PublicRead
        case "PublicReadWrite"            => PublicReadWrite
        case "AuthenticatedRead"          => AuthenticatedRead
        case "LogDeliveryWrite"           => LogDeliveryWrite
        case "BucketOwnerRead"            => BucketOwnerRead
        case "BucketOwnerFullControl"     => BucketOwnerFullControl
      }
    }
  }
}

case class `AWS::S3::BucketPolicy`(name: String,
                                   Bucket: Token[String],
                                   PolicyDocument: PolicyDocument,
                                   override val Condition: Option[ConditionRef] = None
) extends Resource[`AWS::S3::BucketPolicy`] {
  def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}
object `AWS::S3::BucketPolicy` extends DefaultJsonProtocol {
  implicit val format: JsonFormat[`AWS::S3::BucketPolicy`] = jsonFormat4(`AWS::S3::BucketPolicy`.apply)
}

case class S3LoggingConfiguration(DestinationBucketName: Option[`AWS::S3::Bucket`] = None,
                                  LogFilePrefix:         Option[String] = None)
object S3LoggingConfiguration extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3LoggingConfiguration] = jsonFormat2(S3LoggingConfiguration.apply)
}

case class TopicConfigurations(TopicConfigurations: Seq[TopicConfiguration])
object TopicConfigurations extends DefaultJsonProtocol {
  implicit val format: JsonFormat[TopicConfigurations] = jsonFormat1(TopicConfigurations.apply)
}

case class TopicConfiguration(Event: S3Event,
                              Topic: Token[`AWS::SNS::Topic`])
object TopicConfiguration extends DefaultJsonProtocol {
  implicit val format: JsonFormat[TopicConfiguration] = jsonFormat2(TopicConfiguration.apply)
}

/**
 * S3 events
 * http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-event-types-and-destinations
 */<commit_msg>fix bug: S3LoggingConfiguration.DestinationBucketName should be a ResourceRef to a bucket, not an actual bucket<commit_after>package com.monsanto.arch.cloudformation.model.resource

import com.monsanto.arch.cloudformation.model.{ResourceRef, ConditionRef, Token}
import spray.json._

/**
 * Created by bkrodg on 3/30/15.
 */
case class `AWS::S3::Bucket`(name:                      String,
                             BucketName:                Option[Token[String]],
                             AccessControl:             Option[S3AccessControl] = None,
                             CorsConfiguration:         Option[S3CorsRules] = None,
                             LifecycleConfiguration:    Option[S3LifecycleConfigurationRules] = None,
                             LoggingConfiguration:      Option[S3LoggingConfiguration] = None,
                             NotificationConfiguration: Option[TopicConfigurations] = None,
                             VersioningConfiguration:   Option[S3VersioningConfiguration] = None,
                             WebsiteConfiguration:      Option[S3WebsiteConfiguration] = None,
                             Tags:                      Option[Seq[AmazonTag]] = None,
                             override val Condition:    Option[ConditionRef] = None) extends Resource[`AWS::S3::Bucket`] {
  def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}
object `AWS::S3::Bucket` extends DefaultJsonProtocol {
  implicit val format: JsonFormat[`AWS::S3::Bucket`] = jsonFormat11(`AWS::S3::Bucket`.apply)
}

case class S3CorsRules(CorsRules: Seq[S3CorsRule])
object S3CorsRules extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3CorsRules] = jsonFormat1(S3CorsRules.apply)
}

case class S3CorsRule(AllowedMethods: Seq[String],
                      AllowedOrigins: Seq[String],
                      AllowedHeaders: Option[Seq[String]],
                      ExposedHeaders: Option[Seq[String]],
                      Id:             Option[String],
                      MaxAge:         Option[Int])
object S3CorsRule extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3CorsRule] = jsonFormat6(S3CorsRule.apply)
}

case class S3LifecycleConfigurationRules(Rules: Seq[S3LifecycleConfigurationRule])
object S3LifecycleConfigurationRules extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3LifecycleConfigurationRules] = jsonFormat1(S3LifecycleConfigurationRules.apply)
}

case class S3LifecycleConfigurationRule(Status: S3LifecycleConfigurationRuleStatus,
                                        ExpirationDate: Option[String],
                                        ExpirationInDays: Option[Int],
                                        Id: Option[String],
                                        Prefix: Option[String],
                                        Transition: Option[S3LifecycleTransition])
object S3LifecycleConfigurationRule extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3LifecycleConfigurationRule] = jsonFormat6(S3LifecycleConfigurationRule.apply)
}

case class S3LifecycleTransition(StorageClass: String,
                                 TransitionDate: Option[String],
                                 TransitionInDays: Option[Int])
object S3LifecycleTransition extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3LifecycleTransition] = jsonFormat3(S3LifecycleTransition.apply)
}

sealed trait S3LifecycleConfigurationRuleStatus
object S3LifecycleConfigurationRuleStatus extends DefaultJsonProtocol {
  case object Enabled extends S3LifecycleConfigurationRuleStatus
  case object Disabled extends S3LifecycleConfigurationRuleStatus

  implicit val format: JsonFormat[S3LifecycleConfigurationRuleStatus] = new JsonFormat[S3LifecycleConfigurationRuleStatus] {
    override def write(obj: S3LifecycleConfigurationRuleStatus)= JsString(obj.toString)
    override def read(json: JsValue): S3LifecycleConfigurationRuleStatus = {
      json.toString match {
        case "Enabled"  => Enabled
        case "Disabled" => Disabled
      }
    }
  }
}

sealed trait S3AccessControl
object S3AccessControl extends DefaultJsonProtocol {
  case object Private                   extends S3AccessControl
  case object PublicRead                extends S3AccessControl
  case object PublicReadWrite           extends S3AccessControl
  case object AuthenticatedRead         extends S3AccessControl
  case object LogDeliveryWrite          extends S3AccessControl
  case object BucketOwnerRead           extends S3AccessControl
  case object BucketOwnerFullControl    extends S3AccessControl

  implicit val format: JsonFormat[S3AccessControl] = new JsonFormat[S3AccessControl] {
    override def write(obj: S3AccessControl) = JsString(obj.toString)
    override def read(json: JsValue): S3AccessControl = {
      json.toString match {
        case "Private"                    => Private
        case "PublicRead"                 => PublicRead
        case "PublicReadWrite"            => PublicReadWrite
        case "AuthenticatedRead"          => AuthenticatedRead
        case "LogDeliveryWrite"           => LogDeliveryWrite
        case "BucketOwnerRead"            => BucketOwnerRead
        case "BucketOwnerFullControl"     => BucketOwnerFullControl
      }
    }
  }
}

case class `AWS::S3::BucketPolicy`(name: String,
                                   Bucket: Token[String],
                                   PolicyDocument: PolicyDocument,
                                   override val Condition: Option[ConditionRef] = None
) extends Resource[`AWS::S3::BucketPolicy`] {
  def when(newCondition: Option[ConditionRef] = Condition) = copy(Condition = newCondition)
}
object `AWS::S3::BucketPolicy` extends DefaultJsonProtocol {
  implicit val format: JsonFormat[`AWS::S3::BucketPolicy`] = jsonFormat4(`AWS::S3::BucketPolicy`.apply)
}

case class S3LoggingConfiguration(DestinationBucketName: Option[Token[ResourceRef[`AWS::S3::Bucket`]]] = None,
                                  LogFilePrefix:         Option[Token[String]] = None)
object S3LoggingConfiguration extends DefaultJsonProtocol {
  implicit val format: JsonFormat[S3LoggingConfiguration] = jsonFormat2(S3LoggingConfiguration.apply)
}

case class TopicConfigurations(TopicConfigurations: Seq[TopicConfiguration])
object TopicConfigurations extends DefaultJsonProtocol {
  implicit val format: JsonFormat[TopicConfigurations] = jsonFormat1(TopicConfigurations.apply)
}

case class TopicConfiguration(Event: S3Event,
                              Topic: Token[`AWS::SNS::Topic`])
object TopicConfiguration extends DefaultJsonProtocol {
  implicit val format: JsonFormat[TopicConfiguration] = jsonFormat2(TopicConfiguration.apply)
}

/**
 * S3 events
 * http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-event-types-and-destinations
 */
{'fraction_non_alphanumeric': 0.0736780430643035, 'fraction_numerical': 0.012523802548703677, 'mean_word_length': 2.7888457269700333, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '260026', 'n_tokens_mistral': 3408, 'n_tokens_neox': 3378, 'n_words': 720}