<commit_before>module SalesforceBulk
  class Connection
    LOGIN_HOST = 'login.salesforce.com'

    attr_reader :instance
    attr_reader :session_id
    attr_reader :api_version

    def initialize(username, password, api_version, sandbox)
      @username = username
      @password = password
      @api_version = api_version
      @sandbox = sandbox
      login
    end

    def login
      r = SalesforceBulk::Http::Request.create_login(
        @sandbox,
        @username,
        @password,
        @api_version)

      response = request r
      response_parsed = parse_response response

      @session_id = response_parsed['Body'][0]['loginResponse'][0]['result'][0]['sessionId'][0]
      @server_url = response_parsed['Body'][0]['loginResponse'][0]['result'][0]['serverUrl'][0]
      @instance = parse_instance()
    end

    def create_job operation, sobject, external_field
      response = request(SalesforceBulk::Http::Request.create_job(
        @instance,
        @session_id,
        operation,
        sobject,
        @api_version,
        external_field))

      response_parsed = parse_response response
      response_parsed['id'][0]
    end

    def close_job job_id
      response = request(SalesforceBulk::Http::Request.close_job(
        @instance,
        @session_id,
        job_id,
        @api_version))

      puts "====="
      puts "close_job response: #{response.inspect}"
      puts "====="

      response_parsed = parse_response response
      response_parsed['id'][0]
    end

    def add_batch job_id, records
      keys = records.first.keys

      rows = keys.to_csv
      records.each do |r|
        fields = []
        keys.each do |k|
          fields.push(r[k])
        end
        rows << fields.to_csv
      end

      r = SalesforceBulk::Http::Request.add_batch(
        @instance,
        @session_id,
        job_id,
        rows,
        @api_version)

      response = request(r)

      puts '+++++'
      puts "headers of request: #{r.headers.inspect}"
      puts "batch: #{response.inspect}"
      puts '+++++'
      response_parsed = XmlSimple.xml_in(response)

      response_parsed['id'][0]
    end

    def request r
      puts r.inspect
      https(r.host).post(r.path, r.body, r.headers).body
    end

    def get_request(host, path, headers)
      https(host).get(path, headers).body
    end

    def https(host)
      req = Net::HTTP.new(host, 443)
      req.use_ssl = true
      req.verify_mode = OpenSSL::SSL::VERIFY_NONE
      req
    end

    def parse_instance
      #TODO make more ruby like
      @server_url =~ /https:\/\/([a-z]{2,2}[0-9]{1,2})-api/
      @instance = $~.captures[0]
    end

    def parse_response response
      response_parsed = XmlSimple.xml_in(response)

      if response.downcase.include?('faultstring') || response.downcase.include?('exceptionmessage')
        begin
          
          if response.downcase.include?('faultstring')
            error_message = response_parsed['Body'][0]['Fault'][0]['faultstring'][0]
          elsif response.downcase.include?('exceptionmessage')
            error_message = response_parsed['exceptionMessage'][0]
          end

        rescue
          raise "An unknown error has occured within the salesforce_bulk gem. This is most likely caused by bad request, but I am unable to parse the correct error message. Here is a dump of the response for your convenience. #{response}"
        end

        raise error_message
      end

      response_parsed
    end
  end
end<commit_msg>refactor connection to use new http api<commit_after>module SalesforceBulk
  class Connection
    attr_reader :instance
    attr_reader :session_id
    attr_reader :api_version

    def initialize(username, password, api_version, sandbox)
      @username = username
      @password = password
      @api_version = api_version
      @sandbox = sandbox
      login
    end

    def login
      response = SalesforceBulk::Http.login(
        @sandbox,
        @username,
        @password,
        @api_version)

      puts "the login response: #{response.inspect}"

      @session_id = response[:session_id]
      @instance = response[:instance]
    end

    def create_job operation, sobject, external_field
      SalesforceBulk::Http.create_job(
        @instance,
        @session_id,
        operation,
        sobject,
        @api_version,
        external_field)[:id]
    end

    def close_job job_id
      SalesforceBulk::Http.close_job(
        @instance,
        @session_id,
        job_id,
        @api_version)[:id]
    end

    def add_batch job_id, records
      keys = records.first.keys

      rows = keys.to_csv
      records.each do |r|
        fields = []
        keys.each do |k|
          fields.push(r[k])
        end
        rows << fields.to_csv
      end

      SalesforceBulk::Http.add_batch(
        @instance,
        @session_id,
        job_id,
        rows,
        @api_version)[:id]
    end
  end
end
{'fraction_non_alphanumeric': 0.10305112143867448, 'fraction_numerical': 0.005051525560719338, 'mean_word_length': 2.2956058588548602, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '3083253', 'n_tokens_mistral': 1502, 'n_tokens_neox': 1488, 'n_words': 333}