<commit_before>module Adhearsion
  module Twilio
    TwimlError = Class.new Adhearsion::Error # Represents a failure to pass valid TwiML

    TWILIO_CALL_STATUSES = {
      :no_answer => "no-answer",
      :answer => "completed",
      :timeout => "no-answer",
      :error => "failed",
      :in_progress => "in-progress"
    }

    INFINITY = 100
    SLEEP_BETWEEN_REDIRECTS = 1

    module ControllerMethods
      extend ActiveSupport::Concern

      included do
        before_call do
          call.on_end do |event|
            twilio_hangup
          end
        end
      end

      private

      def answered?
        !!@answered
      end

      def answer!
        answer unless answered?
        @answered = true
      end

      def notify_voice_request_url
        execute_twiml(notify_http(config.voice_request_url, config.voice_request_method, :in_progress))
      end

      def redirect(url = nil, options = {})
        execute_twiml(
          notify_http(
            URI.join(@last_request_url, url.to_s).to_s,
            options.delete("method") || "post",
            :in_progress, options
          )
        )
      end

      def notify_status_callback_url
        notify_http(
          config.status_callback_url,
          config.status_callback_method,
          answered? ? :answer : :no_answer,
          :CallDuration => call.duration.to_i,
        ) if config.status_callback_url.present? && config.status_callback_method.present?
      end

      def notify_http(url, method, status, options = {})
        @last_request_url = url
        HTTParty.send(
          method.downcase,
          url,
          :body => {
            :From => normalized_from,
            :To => normalized_to,
            :CallSid => call.id,
            :CallStatus => TWILIO_CALL_STATUSES[status],
            :ApiVersion => api_version
          }.merge(options), :basic_auth => url_auth(url)
        ).body
      end

      def execute_twiml(response)
        redirection = nil
        with_twiml(response) do |node|
          content = node.content
          options = twilio_options(node)
          case node.name
          when 'Reject'
            execute_twiml_verb(:reject, false, options)
            break
          when 'Play'
            execute_twiml_verb(:play, true, content, options)
          when 'Gather'
            break if redirection = execute_twiml_verb(:gather, true, node, options)
          when 'Redirect'
            redirection = execute_twiml_verb(:redirect, true, content, options)
            break
          when 'Hangup'
            break
          when 'Say'
            execute_twiml_verb(:say, true, content, options)
          when 'Pause'
            not_yet_supported!
          when 'Bridge'
            not_yet_supported!
          when 'Dial'
            break if redirection = execute_twiml_verb(:dial, true, node, options)
          else
            raise(ArgumentError, "Invalid element '#{node.name}'")
          end
        end
        redirection ? redirect(*redirection) : hangup<commit_msg>Revert "Answer call for redirect"<commit_after>module Adhearsion
  module Twilio
    TwimlError = Class.new Adhearsion::Error # Represents a failure to pass valid TwiML

    TWILIO_CALL_STATUSES = {
      :no_answer => "no-answer",
      :answer => "completed",
      :timeout => "no-answer",
      :error => "failed",
      :in_progress => "in-progress"
    }

    INFINITY = 100
    SLEEP_BETWEEN_REDIRECTS = 1

    module ControllerMethods
      extend ActiveSupport::Concern

      included do
        before_call do
          call.on_end do |event|
            twilio_hangup
          end
        end
      end

      private

      def answered?
        !!@answered
      end

      def answer!
        answer unless answered?
        @answered = true
      end

      def notify_voice_request_url
        execute_twiml(notify_http(config.voice_request_url, config.voice_request_method, :in_progress))
      end

      def redirect(url = nil, options = {})
        execute_twiml(
          notify_http(
            URI.join(@last_request_url, url.to_s).to_s,
            options.delete("method") || "post",
            :in_progress, options
          )
        )
      end

      def notify_status_callback_url
        notify_http(
          config.status_callback_url,
          config.status_callback_method,
          answered? ? :answer : :no_answer,
          :CallDuration => call.duration.to_i,
        ) if config.status_callback_url.present? && config.status_callback_method.present?
      end

      def notify_http(url, method, status, options = {})
        @last_request_url = url
        HTTParty.send(
          method.downcase,
          url,
          :body => {
            :From => normalized_from,
            :To => normalized_to,
            :CallSid => call.id,
            :CallStatus => TWILIO_CALL_STATUSES[status],
            :ApiVersion => api_version
          }.merge(options), :basic_auth => url_auth(url)
        ).body
      end

      def execute_twiml(response)
        redirection = nil
        with_twiml(response) do |node|
          content = node.content
          options = twilio_options(node)
          case node.name
          when 'Reject'
            execute_twiml_verb(:reject, false, options)
            break
          when 'Play'
            execute_twiml_verb(:play, true, content, options)
          when 'Gather'
            break if redirection = execute_twiml_verb(:gather, true, node, options)
          when 'Redirect'
            redirection = execute_twiml_verb(:redirect, false, content, options)
            break
          when 'Hangup'
            break
          when 'Say'
            execute_twiml_verb(:say, true, content, options)
          when 'Pause'
            not_yet_supported!
          when 'Bridge'
            not_yet_supported!
          when 'Dial'
            break if redirection = execute_twiml_verb(:dial, true, node, options)
          else
            raise(ArgumentError, "Invalid element '#{node.name}'")
          end
        end
        redirection ? redirect(*redirection) : hangup
{'fraction_non_alphanumeric': 0.08633327903567356, 'fraction_numerical': 0.001303143834500733, 'mean_word_length': 1.8386500231160425, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6804968', 'n_tokens_mistral': 1798, 'n_tokens_neox': 1738, 'n_words': 387}