require 'spec_helper'
require 'fileutils'

# these tests avoid the use of ActiveRecord and FactoryGirl to do blackbox, non test-instrumented tests
describe AudioMixer do

  include UsesTempFiles

  let(:quick_mix) { FactoryGirl.create(:quick_mix, started_at: nil, should_retry: false) }


  before(:each) do
    stub_const("APP_CONFIG", app_config)
    module EM
      @next_tick_queue = []
    end

    MQRouter.client_exchange = double("client_exchange")
    MQRouter.user_exchange = double("user_exchange")
    MQRouter.subscription_exchange = double("subscription_exchange")
    MQRouter.client_exchange.should_receive(:publish).any_number_of_times
    MQRouter.user_exchange.should_receive(:publish).any_number_of_times
    MQRouter.subscription_exchange.should_receive(:publish).any_number_of_times
  end

  def assert_found_job_count(expected)
    count = 0
    QuickMixer.find_jobs_needing_retry do
      count = count + 1
    end
    count.should == expected
  end

  describe "queue_jobs_needing_retry" do
    it "won't find anything if no quick mixes" do
      assert_found_job_count(0)
    end

    it "won't find a quick mix that hasn't been started" do
      quick_mix.touch

      assert_found_job_count(0)
    end

    it "won't find a quick mix that has should_retry flagged" do
      quick_mix.should_retry = true
      quick_mix.save!

      assert_found_job_count(1)
    end

    it "won't find a quick mix that has should_retry flagged" do
      quick_mix.should_retry = false
      quick_mix.started_at = 2.hours.ago
      quick_mix.save!

      assert_found_job_count(1)
    end
  end


  # these tests try to run the job with minimal faking.   Here's what we still fake:
  # we don't run audiomixer. audiomixer is tested already
  # we don't run redis and actual resque, because that's tested by resque/resque-spec
  describe "full", :aws => true do


    sample_ogg='sample.ogg'
    in_directory_with_file(sample_ogg)


    before(:each) do
      content_for_file("ogg goodness")
      @user = FactoryGirl.create(:user)
      @connection = FactoryGirl.create(:connection, :user => @user)
      @instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
      @track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
      @music_session = FactoryGirl.create(:active_music_session, :creator => @user, :musician_access => true)
      # @music_session.connections << @connection
      @music_session.save
      @connection.join_the_session(@music_session, true, [@track], @user, 10)
      @recording = Recording.start(@music_session, @user)
      @recording.stop
      @recording.claim(@user, "name", "description", Genre.first, true)
      @recording.errors.any?.should be_false
      @recording.quick_mixes.length.should == 1
      @quick_mix = @recording.quick_mixes[0]

      test_config = app_config

      @s3_manager = S3Manager.new(test_config.aws_bucket, test_config.aws_access_key_id, test_config.aws_secret_access_key)

      # put a file in s3
      @s3_manager.upload(@quick_mix[:ogg_url], sample_ogg)

      # create a signed url that the job will use to fetch it back down
      @s3_sample = @s3_manager.sign_url(@quick_mix[:ogg_url], :secure => false)

      QuickMixer.any_instance.stub(:create_mp3) do |input_file, output_file|
        FileUtils.mv input_file, output_file
      end
    end

    it "completes" do
      with_resque do
        #QuickMix.any_instance.stub(:manifest).and_return(s3_manifest)
        @mix = @recording.quick_mixes[0]
        @mix.enqueue
      end

      @mix.reload
      @mix.completed.should be_true
      @mix.mp3_length.should == "ogg goodness".length
      @mix.mp3_md5.should == ::Digest::MD5.file(sample_ogg).hexdigest

      # fetch back the mp3 file from s3, check that it's equivalent to the sample_ogg file (which we did a FileUtils.mv of to make a fake mp3)
      mp3_fetched_from_s3 = Tempfile.new('foo')
      @s3_manager.download(@quick_mix[:mp3_url], mp3_fetched_from_s3.path)
      @mix.mp3_md5.should == ::Digest::MD5.file(mp3_fetched_from_s3).hexdigest

    end
  end
end
