AWSTemplateFormatVersion: '2010-09-09'
Description: >-
  Private encrypted S3 storage and a read-only CloudFront distribution for
  redacted EG334S demonstration chapters. Raw masters remain private.

Parameters:
  RawRetentionDays:
    Type: Number
    Default: 45
    MinValue: 7
    MaxValue: 180
  PublicRetentionDays:
    Type: Number
    Default: 75
    MinValue: 30
    MaxValue: 365

Resources:
  RecordingBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      OwnershipControls:
        Rules:
          - ObjectOwnership: BucketOwnerEnforced
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        IgnorePublicAcls: true
        BlockPublicPolicy: true
        RestrictPublicBuckets: true
      VersioningConfiguration:
        Status: Enabled
      LifecycleConfiguration:
        Rules:
          - Id: ExpireRawMasters
            Status: Enabled
            Prefix: raw/
            ExpirationInDays: !Ref RawRetentionDays
            NoncurrentVersionExpiration:
              NoncurrentDays: 7
          - Id: ExpireRedactedExports
            Status: Enabled
            Prefix: public/
            ExpirationInDays: !Ref PublicRetentionDays
            NoncurrentVersionExpiration:
              NoncurrentDays: 7
      Tags:
        - { Key: Project, Value: EG334S }
        - { Key: Purpose, Value: DemonstrationEvidence }

  OriginAccessControl:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        Name: !Sub '${AWS::StackName}-s3-oac'
        Description: CloudFront-only access to redacted EG334S recordings
        OriginAccessControlOriginType: s3
        SigningBehavior: always
        SigningProtocol: sigv4

  Distribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        Comment: Redacted EG334S demonstration chapters
        HttpVersion: http2and3
        IPV6Enabled: true
        PriceClass: PriceClass_100
        Origins:
          - Id: RecordingBucketOrigin
            DomainName: !GetAtt RecordingBucket.RegionalDomainName
            OriginAccessControlId: !GetAtt OriginAccessControl.Id
            S3OriginConfig:
              OriginAccessIdentity: ''
        DefaultCacheBehavior:
          TargetOriginId: RecordingBucketOrigin
          ViewerProtocolPolicy: redirect-to-https
          Compress: true
          AllowedMethods: [GET, HEAD, OPTIONS]
          CachedMethods: [GET, HEAD, OPTIONS]
          CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
          ResponseHeadersPolicyId: 67f7725c-6f97-4210-82d7-5512b31e9d03
      Tags:
        - { Key: Project, Value: EG334S }
        - { Key: Purpose, Value: DemonstrationEvidence }

  RecordingBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref RecordingBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: CloudFrontReadRedactedExports
            Effect: Allow
            Principal:
              Service: cloudfront.amazonaws.com
            Action: s3:GetObject
            Resource: !Sub '${RecordingBucket.Arn}/public/*'
            Condition:
              StringEquals:
                AWS:SourceArn: !Sub 'arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${Distribution}'

Outputs:
  RecordingBucketName:
    Value: !Ref RecordingBucket
  DistributionDomainName:
    Value: !GetAtt Distribution.DomainName
  PublicChapterBaseUrl:
    Value: !Sub 'https://${Distribution.DomainName}/public/'
  RawMasterPrefix:
    Value: !Sub 's3://${RecordingBucket}/raw/'
