<commit_before>module Setup
  class Webhook
    include CenitScoped
    include NamespaceNamed
    include ParametersCommon
    include JsonMetadata
    include AuthorizationHandler

    BuildInDataType.regist(self).referenced_by(:namespace, :name).excluding(:connection_roles)

    embeds_many :parameters, class_name: Setup::Parameter.to_s, inverse_of: :webhook
    embeds_many :headers, class_name: Setup::Parameter.to_s, inverse_of: :webhook

    embeds_many :template_parameters, class_name: Setup::Parameter.to_s, inverse_of: :webhook

    field :path, type: String
    field :method, type: String, default: :post
    field :description, type: String

    def method_enum
      [:get, :post, :put, :delete, :patch, :copy, :head, :options, :link, :unlink, :purge, :lock, :unlock, :propfind]
    end

    validates_presence_of :path

    accepts_nested_attributes_for :parameters, :headers, :template_parameters, allow_destroy: true

    def conformed_path(options = {})
      conform_field_value(:path, options)
    end

    def upon(connections, options = {})
      @connections = connections
      @connection_role_options = options || {}
      self
    end

    def connections
      if @connections_cache
        @connections_cache
      else
        connections =
          if @connections
            @connections.is_a?(Setup::Connection) ? [@connections] : (@connections.connections || [])
          else
            connections = []
            Setup::ConnectionRole.all.each do |connection_role|
              if connection_role.webhooks.include?(self)
                connections = (connections + connection_role.connections.to_a).uniq
              end
            end
            connections
          end
        @connections_cache = connections unless @connection_role_options &&
          @connection_role_options.has_key?(:cache) &&
          !@connection_role_options[:cache]
        connections
      end
    end

    def submit(*args, &block)
      if (options = args[0]).is_a?(Hash)
        body_argument = options[:body]
      else
        body_argument = options
        options = args[1] || {}
      end
      last_response = nil
      template_parameters_hash = self.template_parameters_hash.merge!(options[:template_parameters] || {})
      verbose_response = options[:verbose_response] ? {} : nil
      if (connections = self.connections).present?
        verbose_response[:connections_present] = true if verbose_response
        common_submitter_body = (body_caller = body_argument.respond_to?(:call)) ? nil : body_argument
        common_template_parameters = nil
        connections.each do |connection|
          template_parameters = template_parameters_hash.dup
          template_parameters.reverse_merge!(connection.template_parameters_hash)
          submitter_body =
            if body_caller
              body_argument.call(template_parameters)
            else
              common_submitter_body
            end
          submitter_body = '' if body_argument && submitter_body.nil?
          if [Hash, Array, String, NilClass].include?(submitter_body.class)
            case submitter_body
            when Hash
              if options[:contentType] == 'application/json'
                body = submitter_body.to_json
              else
                body = {}
                submitter_body.each do |key, content|
                  body[key] =
                    if content.is_a?(String) || content.respond_to?(:read)
                      content
                    elsif content.is_a?(Hash)
                      UploadIO.new(StringIO.new(content[:data]), content[:contentType], content[:filename])
                    else
                      content.to_s
                    end
                end
              end
            when Array
              body = submitter_body.to_json
            else
              body = submitter_body
            end
            template_parameters.reverse_merge!(
              url: conformed_url = connection.conformed_url(template_parameters),
              path: conformed_path = conformed_path(template_parameters),
              method: method
            )
            template_parameters[:body] = body if body

            parameters = connection.conformed_parameters(template_parameters).
              merge(conformed_parameters(template_parameters)).
              merge!(options[:parameters] || {}).
              reject { |_, value| value.blank? }

            template_parameters[:query_parameters] = parameters
            connection.inject_other_parameters(parameters, template_parameters)
            inject_other_parameters(parameters, template_parameters)

            query = parameters.to_param
            template_parameters[:query] = query

            headers = {}
            headers['Content-Type'] = options[:contentType] if options.has_key?(:contentType)
            headers.merge!(connection.conformed_headers(template_parameters)).
              merge!(conformed_headers(template_parameters)).
              merge!(options[:headers] || {}).
              reject! { |_, value| value.nil? }
            begin
              if query.present?
                conformed_path += '?' + query
              end
              url = conformed_url + ('/' + conformed_path).gsub(/\/+/, '/')
              if body
                attachment = {
                  filename: DateTime.now.strftime('%Y-%m-%d_%Hh%Mm%S'),
                  contentType: options[:contentType] || 'application/octet-stream',
                  body: body
                }
                if (request_attachment = options[:request_attachment]).respond_to?(:call)
                  attachment = request_attachment.call(attachment)
                end
              else
                attachment = nil
              end
              Setup::Notification.create_with(message: JSON.pretty_generate(method: method,
                                                                            url: url,
                                                                            headers: headers),
                                              type: :notice,
                                              attachment: attachment,
                                              skip_notification_level: options[:skip_notification_level] || options[:notify_request])

              msg = { headers: headers }
              msg[:body] = body if body
              msg[:timeout] = 240 if true #custom_timeout
              msg[:verify] = false if true #custom_timeout
              http_response = HTTMultiParty.send(method, url, msg)
              last_response = http_response.body

              Setup::Notification.create_with(message: { response_code: http_response.code }.to_json,
                                              type: (200...299).include?(http_response.code) ? :notice : :error,<commit_msg>Verify HTTPS TODO<commit_after>module Setup
  class Webhook
    include CenitScoped
    include NamespaceNamed
    include ParametersCommon
    include JsonMetadata
    include AuthorizationHandler

    BuildInDataType.regist(self).referenced_by(:namespace, :name).excluding(:connection_roles)

    embeds_many :parameters, class_name: Setup::Parameter.to_s, inverse_of: :webhook
    embeds_many :headers, class_name: Setup::Parameter.to_s, inverse_of: :webhook

    embeds_many :template_parameters, class_name: Setup::Parameter.to_s, inverse_of: :webhook

    field :path, type: String
    field :method, type: String, default: :post
    field :description, type: String

    def method_enum
      [:get, :post, :put, :delete, :patch, :copy, :head, :options, :link, :unlink, :purge, :lock, :unlock, :propfind]
    end

    validates_presence_of :path

    accepts_nested_attributes_for :parameters, :headers, :template_parameters, allow_destroy: true

    def conformed_path(options = {})
      conform_field_value(:path, options)
    end

    def upon(connections, options = {})
      @connections = connections
      @connection_role_options = options || {}
      self
    end

    def connections
      if @connections_cache
        @connections_cache
      else
        connections =
          if @connections
            @connections.is_a?(Setup::Connection) ? [@connections] : (@connections.connections || [])
          else
            connections = []
            Setup::ConnectionRole.all.each do |connection_role|
              if connection_role.webhooks.include?(self)
                connections = (connections + connection_role.connections.to_a).uniq
              end
            end
            connections
          end
        @connections_cache = connections unless @connection_role_options &&
          @connection_role_options.has_key?(:cache) &&
          !@connection_role_options[:cache]
        connections
      end
    end

    def submit(*args, &block)
      if (options = args[0]).is_a?(Hash)
        body_argument = options[:body]
      else
        body_argument = options
        options = args[1] || {}
      end
      last_response = nil
      template_parameters_hash = self.template_parameters_hash.merge!(options[:template_parameters] || {})
      verbose_response = options[:verbose_response] ? {} : nil
      if (connections = self.connections).present?
        verbose_response[:connections_present] = true if verbose_response
        common_submitter_body = (body_caller = body_argument.respond_to?(:call)) ? nil : body_argument
        common_template_parameters = nil
        connections.each do |connection|
          template_parameters = template_parameters_hash.dup
          template_parameters.reverse_merge!(connection.template_parameters_hash)
          submitter_body =
            if body_caller
              body_argument.call(template_parameters)
            else
              common_submitter_body
            end
          submitter_body = '' if body_argument && submitter_body.nil?
          if [Hash, Array, String, NilClass].include?(submitter_body.class)
            case submitter_body
            when Hash
              if options[:contentType] == 'application/json'
                body = submitter_body.to_json
              else
                body = {}
                submitter_body.each do |key, content|
                  body[key] =
                    if content.is_a?(String) || content.respond_to?(:read)
                      content
                    elsif content.is_a?(Hash)
                      UploadIO.new(StringIO.new(content[:data]), content[:contentType], content[:filename])
                    else
                      content.to_s
                    end
                end
              end
            when Array
              body = submitter_body.to_json
            else
              body = submitter_body
            end
            template_parameters.reverse_merge!(
              url: conformed_url = connection.conformed_url(template_parameters),
              path: conformed_path = conformed_path(template_parameters),
              method: method
            )
            template_parameters[:body] = body if body

            parameters = connection.conformed_parameters(template_parameters).
              merge(conformed_parameters(template_parameters)).
              merge!(options[:parameters] || {}).
              reject { |_, value| value.blank? }

            template_parameters[:query_parameters] = parameters
            connection.inject_other_parameters(parameters, template_parameters)
            inject_other_parameters(parameters, template_parameters)

            query = parameters.to_param
            template_parameters[:query] = query

            headers = {}
            headers['Content-Type'] = options[:contentType] if options.has_key?(:contentType)
            headers.merge!(connection.conformed_headers(template_parameters)).
              merge!(conformed_headers(template_parameters)).
              merge!(options[:headers] || {}).
              reject! { |_, value| value.nil? }
            begin
              if query.present?
                conformed_path += '?' + query
              end
              url = conformed_url + ('/' + conformed_path).gsub(/\/+/, '/')
              if body
                attachment = {
                  filename: DateTime.now.strftime('%Y-%m-%d_%Hh%Mm%S'),
                  contentType: options[:contentType] || 'application/octet-stream',
                  body: body
                }
                if (request_attachment = options[:request_attachment]).respond_to?(:call)
                  attachment = request_attachment.call(attachment)
                end
              else
                attachment = nil
              end
              Setup::Notification.create_with(message: JSON.pretty_generate(method: method,
                                                                            url: url,
                                                                            headers: headers),
                                              type: :notice,
                                              attachment: attachment,
                                              skip_notification_level: options[:skip_notification_level] || options[:notify_request])

              msg = { headers: headers }
              msg[:body] = body if body
              msg[:timeout] = 240 #TODO Custom timeout request
              msg[:verify] = false #TODO Https varify option by Connection

              Setup::Notification.create_with(message: { response_code: http_response.code }.to_json,
                                              type: (200...299).include?(http_response.code) ? :notice : :error,
{'fraction_non_alphanumeric': 0.08813856610392458, 'fraction_numerical': 0.0016078345392092376, 'mean_word_length': 1.8514273807043133, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4197898', 'n_tokens_mistral': 3354, 'n_tokens_neox': 3233, 'n_words': 663}