class SubscribeController < ApplicationController
  skip_before_action :verify_authenticity_token
  def verify
    _log :info, "Verify request: #{params.inspect}"

    mode      = params.require('hub.mode')
    topic     = params.require('hub.topic')
    challenge = params.require('hub.challenge')
    lease_sec = params['hub.lease_seconds']

    unless %w(subscribe unsubscribe).member? mode
      _log :error, "Invalid veiry request: mode=#{mode}"
      raise ProcessError.new(status: 404, message: "Invalid mode")
    end

    render plain: challenge, status: 200
  end

  def distribute
    req_body = request.body.read
    if req_body.blank?
      _log :warn, "Empty body for distribute request! Skip all"
      return head 200
    end

    require 'openssl'

    sig = request.headers['X-Hub-Signature']
    if sig.blank?
      _log :error, "Hub signature is missing. Returning error!"
      return head 400
    elsif sig !~ /^(sha1|sha256)=\S+/
      _log :error, "Unknown hub signature format: #{sig}, returning error!"
      return head 400
    end
    sig_type = $1

    hub = nil
    [*request.headers['Link']].each do |link|
      link.tr!("\r\n", ' ')
      link =~ /;\s*rel=hub\b/ or next
      link =~ /^\s*<([^>]+)>/
      hub = $1
    end
    secret = Rails.configuration.hub_secrets[hub] || Rails.configuration.hub_secret_default
    digest_class = sig_type == "sha256" ? OpenSSL::Digest::SHA256 : OpenSSL::Digest::SHA1
    hmac = OpenSSL::HMAC::hexdigest(digest_class.new, secret.to_s, req_body)

    if "#{sig_type}=#{hmac}" != sig.strip
      _log :error, "Invalid hub signature (#{sig}), returning error!"
      return head 400
    end

    ds = DistSignal.create! signature: sig,
      body: req_body.to_s.force_encoding('utf-8').scrub('?'),
      content_type: request.headers['Content-Type'],
      link: request.headers['Link']

    FetchJmaContentJob.perform_later(ds)

    head 200
  end
end
