# typed: strict
class HttpLogEntryHeader < ReduxApplicationRecord
  validates_presence_of(:sha256)
  validates :sha256, length: { is: 32 }

  sig { params(headers: T::Hash[String, String]).returns(HttpLogEntryHeader) }
  def self.build(headers:)
    headers = headers.dup
    scrub_header(headers, "etag")
    scrub_header(headers, "content-length")
    scrub_header(headers, "cache-control")
    scrub_header(headers, "perf")
    scrub_header(headers, "x-connection-hash")
    scrub_header(headers, "x-transaction-id")
    scrub_header(headers, "x-rate-limit-remaining")
    scrub_header(headers, "x-rate-limit-reset")
    scrub_header(headers, "x-response-time")
    scrub_datetime_header(headers, "expires")
    scrub_datetime_header(headers, "last-modified")
    scrub_datetime_header(headers, "date")

    if ray = headers["cf-ray"]
      ray = ray.split("-")
      ray[0] = "(scrubbed)"
      headers["cf-ray"] = ray.join("-")
    end

    headers = headers.sort.to_h
    sha256 = Digest::SHA256.digest(headers.to_s)
    HttpLogEntryHeader.new(sha256: sha256, headers: headers)
  end

  sig { params(headers: T::Hash[String, String]).returns(HttpLogEntryHeader) }
  def self.find_or_build(headers:)
    record = build(headers: headers)
    find_by(sha256: record.sha256) || record
  end

  sig { params(headers: T::Hash[String, String]).returns(HttpLogEntryHeader) }
  def self.find_or_create(headers:)
    record = find_or_build(headers: headers)
    record.save! unless record.persisted?
    record
  end

  sig { params(headers: T::Hash[String, String], key: String).void }
  def self.scrub_header(headers, key)
    headers[key] = "(scrubbed)" if headers[key]
  end

  sig { params(headers: T::Hash[String, String], key: String).void }
  def self.scrub_datetime_header(headers, key)
    if value = headers[key]
      value.gsub!(/\d\d:\d\d:\d\d/, "(scrubbed)")
      headers[key] = value
    end
  end

  sig { returns(HttpLogEntryHeader) }
  def self.empty
    @empty_model ||=
      T.let(self.find_or_create(headers: {}), T.nilable(HttpLogEntryHeader))
  end
end
