# frozen_string_literal: true

require 'dry/struct'
require 'netaddr'
require 'twitch/audit/mixins/partial'
require 'twitch/audit/models/types'

module Twitch
  module Audit

    DEFAULT_TRUSTED_SUBNETS = [
      '10.0.0.0/8',
      '127.16.0.0/12',
      '192.168.0.0/16',
      '127.0.0.1/8',
      NetAddr::CIDR.create('::1/128')
    ].freeze

    # Structured data for audit client config information
    class ClientConfiguration < Dry::Struct
      extend Mixins::Partial

      # @!attribute [rw]
      # S3 bucket to use for dead-letter submissions
      # @return [String]
      attribute :dead_letter_bucket, Types::Strict::String.constrained(
        format: /(?=^.{3,63}$)(?!^(\d+\.)+\d+$)(^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$)/
      )

      # @!attribute [rw]
      # Friendly name for the consuming service
      # @return [String]
      attribute :service_name, Types::Coercible::String

      # @!attribute [rw]
      # What sns topic are we writing to
      # @return [String]
      attribute :sns_topic_arn, Types::Strict::String.constrained(
        format: /^arn:aws:sns:[-a-z0-9]+:[0-9]{12}:[0-9a-z_-]+$/
      )

      # @!attribute [rw]
      # How many items to submit each interval
      # @return [String]
      attribute :submission_batch_size, Types::Strict::Integer.default(10)

      # @!attribute [rw]
      # How long, in seconds, we should let a batch be attempted before it's abandoned
      # @return [String]
      attribute :submission_timeout, Types::Strict::Integer.default(30)

      # @!attribute [rw]
      # Time between submissions in seconds
      # @return [String]
      attribute :submission_interval, Types::Strict::Integer.default(1)

      # @!attribute [rw]
      # Trusted network subnets for X-Forwarded-For validation
      # @return [Array<>]
      attribute :trusted_subnets, Types::SubnetArray.default(DEFAULT_TRUSTED_SUBNETS)
    end
  end
end
