# frozen_string_literal: true

module Diffend
  module HandleErrors
    # Module responsible for reporting errors to diffend
    module Report
      class << self
        # Execute request to Diffend
        #
        # @param exception [Exception] expection that was raised
        # @param payload [Hash] with versions to check
        # @param config [OpenStruct] Diffend config
        # @param message [Symbol] message that we want to display
        # @param report [Boolean] if true we will report the issue to diffend
        # @param raise_exception [Boolean] if true we will raise an exception
        #
        # @return [Net::HTTPResponse] response from Diffend
        def call(config:, message:, exception: nil, payload: {}, report: false, raise_exception: true)
          exception_payload = prepare_exception_payload(exception, payload)

          Bundler.ui.error(Diffend::HandleErrors::Messages::PAYLOAD_DUMP)
          Bundler.ui.error(Diffend::HandleErrors::Messages.const_get(message.to_s.upcase))

          if report
            Diffend::Request.call(
              build_request_object(config, exception_payload)
            )
          end

          raise Diffend::Errors::HandledException if raise_exception
        end

        # @param config [OpenStruct] diffend config
        # @param payload [Hash]
        #
        # @return [Diffend::RequestObject]
        def build_request_object(config, payload)
          Diffend::RequestObject.new(
            config: config,
            url: errors_url(config.project_id),
            payload: payload,
            request_method: :post
          )
        end

        # Prepare exception payload and display it to stdout
        #
        # @param exception [Exception] expection that was raised
        # @param payload [Hash] with versions to check
        #
        # @return [Hash]
        def prepare_exception_payload(exception, payload)
          Diffend::HandleErrors::BuildExceptionPayload
            .call(exception, payload)
            .tap(&Diffend::HandleErrors::DisplayToStdout.method(:call))
        end

        # Provides diffend errors endpoint url
        #
        # @param project_id [String] diffend project_id
        #
        # @return [String] diffend endpoint
        def errors_url(project_id)
          return ENV['DIFFEND_ERROR_URL'] if ENV.key?('DIFFEND_ERROR_URL')

          "https://my.diffend.io/api/projects/#{project_id}/errors"
        end
      end
    end
  end
end