class ExampleClient
  include PWork::Async

  def http_method
    # sleep for 200ms to simulate a blocking http call
    sleep(0.2)
  end

  def multi_call_async
    async do
      http_method
    end
    async do
      http_method
    end
    async do
      http_method
    end
    async do
      http_method
    end
    async do
      http_method
    end
    async do
      http_method
    end
    async do
      http_method
    end
    async do
      http_method
    end
    async do
      http_method
    end
    async wait: false do
      http_method
    end
  end

  def async_thread_storage
    @request_id = nil
    async do
      @request_id = Thread.current[:request][:id]
    end
    async :wait
    @request_id
  end

  def wait
    async :wait
  end
end

RSpec.describe ExampleClient do
  before do
    PWork::Async.reset
  end
  context 'when async mode is :thread' do
    before do
      ENV['PWORK_ASYNC_MODE'] = 'thread'
    end
    it 'makes multiple http calls asyncronously' do
      subject.multi_call_async
      expect(PWork::Async.tasks.length).to eq 9
      started = Time.now.to_f
      subject.wait
      completed = Time.now.to_f
      duration = completed - started
      expect(duration).to be < 0.3
      expect(PWork::Async.tasks.length).to eq 0
    end
    let(:request_id) { SecureRandom.uuid }
    it 'copies thread local storage into async threads' do
      Thread.current[:request] = { id: request_id }
      expect(subject.async_thread_storage).to eq request_id
    end
    after do
      ENV['PWORK_ASYNC_MODE'] = nil
    end
  end
  unless RUBY_PLATFORM =~ /java/
    context 'when async mode is :fork' do
      before do
        ENV['PWORK_ASYNC_MODE'] = 'fork'
      end
      it 'makes multiple http calls asyncronously' do
        subject.multi_call_async
        expect(PWork::Async.tasks.length).to eq 9
        subject.wait
        expect(PWork::Async.tasks.length).to eq 0
      end
      after do
        ENV['PWORK_ASYNC_MODE'] = nil
      end
    end
  end
  context 'when async mode is :test' do
    before do
      ENV['PWORK_ASYNC_MODE'] = 'test'
    end
    it 'makes multiple http calls asyncronously' do
      subject.multi_call_async
      subject.wait
    end
    after do
      ENV['PWORK_ASYNC_MODE'] = nil
    end
  end
end
