=begin

require 'spec_helper'

describe LessonSessionAnalyser do

  let(:user) { FactoryGirl.create(:user, remaining_test_drives: 1) }
  let(:teacher) { FactoryGirl.create(:teacher_user) }
  let(:start) { Time.now }
  let(:lesson_booking_slot_single1) { FactoryGirl.build(:lesson_booking_slot_single) }
  let(:lesson_booking_slot_single2) { FactoryGirl.build(:lesson_booking_slot_single) }
  let(:lesson_booking_slot_recurring1) { FactoryGirl.build(:lesson_booking_slot_recurring) }
  let(:lesson_booking_slot_recurring2) { FactoryGirl.build(:lesson_booking_slot_recurring) }
  let(:valid_single_slots) { [lesson_booking_slot_single1, lesson_booking_slot_single2] }
  let(:valid_recurring_slots) { [lesson_booking_slot_recurring1, lesson_booking_slot_recurring2] }

  describe "analyse" do

    after{
      Timecop.return
    }
    it "neither show" do
      lesson = testdrive_lesson(user, teacher)
      music_session = lesson.music_session

      Timecop.freeze((lesson.music_session.scheduled_start + lesson.duration * 60) + 1)

      analysis = LessonSessionAnalyser.analyse(lesson)
      analysis[:reason].should eql LessonSessionAnalyser::TEACHER_FAULT
      analysis[:student].should eql nil
      analysis[:bill].should be false

      student = analysis[:student_analysis]
      student[:joined_on_time].should be false
      student[:joined_late].should be false
      student[:waited_correctly].should be false
      student[:initial_waiting_pct].should eql nil
      student[:potential_waiting_time].should eql nil

      together = analysis[:together_analysis]
      together[:session_time].should eql 0
    end

    it "teacher joined on time, waited, student no show" do
      lesson = testdrive_lesson(user, teacher)
      music_session = lesson.music_session

      # create some bogus, super-perfect teacher/student times
      start = lesson.scheduled_start
      end_time = lesson.scheduled_start + (60 * lesson.duration)
      uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: music_session, created_at: start, session_removed_at: end_time)
      Timecop.travel(end_time + 1)


      analysis = LessonSessionAnalyser.analyse(lesson)
      analysis[:reason].should eql LessonSessionAnalyser::STUDENT_FAULT
      analysis[:student].should eql LessonSessionAnalyser::NO_SHOW
      analysis[:bill].should be true

      student = analysis[:student_analysis]
      student[:joined_on_time].should be false
      student[:joined_late].should be false
      student[:waited_correctly].should be false
      student[:initial_waiting_pct].should eql nil
        student[:potential_waiting_time].should eql nil

      together = analysis[:together_analysis]
      together[:session_time].should eql 0
    end

    it "student joined 1 min before start time, is waiting for  12 minutes" do
      lesson = testdrive_lesson(user, teacher)
      music_session = lesson.music_session

      # create some bogus, super-perfect teacher/student times
      start = lesson.scheduled_start
      end_time = lesson.scheduled_start + (60 * lesson.duration)
      uh2 = FactoryGirl.create(:music_session_user_history, user: user, history: music_session, created_at: start - 60, session_removed_at: nil)

      Timecop.freeze(start + 11 * 60)

      analysis = LessonSessionAnalyser.analyse(lesson, true)
      analysis[:reason].should eql LessonSessionAnalyser::TEACHER_FAULT
      analysis[:teacher].should eql LessonSessionAnalyser::NO_SHOW
      analysis[:student].should be_nil
      analysis[:bill].should be false

      student = analysis[:student_analysis]
      student[:joined_on_time].should be true
      student[:joined_late].should be false
      student[:waited_correctly].should be true
      student[:initial_waiting_pct].should eql 1.0
      student[:potential_waiting_time].should eql 600.0

      student[:session_time].should eql (11 * 60).to_f

      together = analysis[:together_analysis]
      together[:session_time].should eql 0
    end

    it "teacher joined on time, waited, student joined late" do
      lesson = testdrive_lesson(user, teacher)
      music_session = lesson.music_session

      # create some bogus, super-perfect teacher/student times
      start = lesson.scheduled_start
      end_time = lesson.scheduled_start + (60 * lesson.duration)
      late_start = start + (7 * 60)
      uh1 = FactoryGirl.create(:music_session_user_history, user: user, history: music_session, created_at: late_start, session_removed_at: late_start + 4 * 60)
      uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: music_session, created_at: start, session_removed_at: end_time)

      Timecop.travel(end_time + 1)


      analysis = LessonSessionAnalyser.analyse(lesson)
      analysis[:reason].should eql LessonSessionAnalyser::STUDENT_FAULT
      analysis[:student].should eql LessonSessionAnalyser::JOINED_LATE
      analysis[:bill].should be true

      student = analysis[:student_analysis]
      student[:joined_on_time].should be false
      student[:joined_late].should be true
      student[:waited_correctly].should be false
      student[:initial_waiting_pct].should eql nil
      student[:potential_waiting_time].should eql nil

      together = analysis[:together_analysis]
      together[:session_time].should eql (4 * 60.to_f)
    end

    it "together 5 minutes" do

      lesson = testdrive_lesson(user, teacher)
      music_session = lesson.music_session

      analysis = LessonSessionAnalyser.analyse(lesson)
      analysis[:reason].should eql LessonSessionAnalyser::SESSION_ONGOING


      # create some bogus, super-perfect teacher/student times
      start = lesson.scheduled_start
      end_time = lesson.scheduled_start + (60 * lesson.duration)
      uh1 = FactoryGirl.create(:music_session_user_history, user: user, history: music_session, created_at: start, session_removed_at: end_time)
      uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: music_session, created_at: start, session_removed_at: end_time)


      analysis = LessonSessionAnalyser.analyse(lesson)
      analysis[:reason].should eql LessonSessionAnalyser::SESSION_ONGOING

      Timecop.travel(end_time + 1)

      analysis = LessonSessionAnalyser.analyse(lesson)
      analysis[:reason].should eql LessonSessionAnalyser::SUCCESS
      analysis[:bill].should be true

      teacher = analysis[:teacher_analysis]
      teacher[:joined_on_time].should be true
      teacher[:waited_correctly].should be true
      teacher[:initial_waiting_pct].should eql 1.0
      teacher[:potential_waiting_time].should eql 600.0

      together = analysis[:together_analysis]
      together[:session_time].should eql 1800.0
    end
  end

  describe "intersecting_ranges" do

    let(:lesson) { testdrive_lesson(user, teacher) }
    let(:music_session) { lesson.music_session }

    it "empty" do
      LessonSessionAnalyser.intersecting_ranges([], []).should eql []
    end

    it "one specified, other empty" do

      uh1Begin = start
      uh1End = start + 1

      LessonSessionAnalyser.intersecting_ranges([], [Range.new(uh1Begin, uh1End)]).should eql []
      LessonSessionAnalyser.intersecting_ranges([Range.new(uh1Begin, uh1End)], []).should eql []
    end

    it "both identical" do
      uh1Begin = start
      uh1End = start + 1

      LessonSessionAnalyser.intersecting_ranges([Range.new(uh1Begin, uh1End)], [Range.new(uh1Begin, uh1End)]).should eql [Range.new(uh1Begin, uh1End)]
    end

    it "one intersect" do
      uh1Begin = start
      uh1End = start + 4

      uh2Begin = start + 1
      uh2End = start + 3

      LessonSessionAnalyser.intersecting_ranges([Range.new(uh1Begin, uh1End)], [Range.new(uh2Begin, uh2End)]).should eql [Range.new(uh2Begin, uh2End)]
    end

    it "overlapping intersect" do
      uh1Begin = start
      uh1End = start + 4

      uh2Begin = start + -1
      uh2End = start + 2

      uh3Begin = start + 3
      uh3End = start + 5

      LessonSessionAnalyser.intersecting_ranges([Range.new(uh2Begin, uh2End), Range.new(uh3Begin, uh3End)], [Range.new(uh1Begin, uh1End)]).should eql [Range.new(uh1Begin, uh2End), Range.new(uh3Begin, uh1End)]
    end

    it "no overlap" do
      uh1Begin = start
      uh1End = start + 4

      uh2Begin = start + 5
      uh2End = start + 6

      LessonSessionAnalyser.intersecting_ranges([Range.new(uh1Begin, uh1End)], [Range.new(uh2Begin, uh2End)]).should eql []
    end
  end

  describe "merge_overlapping_ranges" do

    let(:lesson) { testdrive_lesson(user, teacher) }
    let(:music_session) { lesson.music_session }


    it "empty" do
      LessonSessionAnalyser.merge_overlapping_ranges([]).should eql []
    end

    it "one item" do
      uh1Begin = start
      uh1End = start + 1

      uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)

      ranges = LessonSessionAnalyser.time_ranges [uh1]

      LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh1End)]
    end

    it "two identical items" do
      uh1Begin = start
      uh1End = start + 1

      uh2Begin = uh1Begin
      uh2End = uh1End

      uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
      uh2 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh2Begin, session_removed_at: uh2End)

      ranges = LessonSessionAnalyser.time_ranges [uh1, uh2]

      LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh1End)]
    end

    it "two separate times" do
      uh1Begin = start
      uh1End = start + 1

      uh2Begin = start + 3
      uh2End = start + 5

      uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
      uh2 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh2Begin, session_removed_at: uh2End)

      ranges = LessonSessionAnalyser.time_ranges [uh1, uh2]

      LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh1End), Range.new(uh2Begin, uh2End)]
    end

    it "two overlapping times" do
      uh1Begin = start
      uh1End = start + 1

      uh2Begin = start + 0.5
      uh2End = start + 5

      uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
      uh2 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh2Begin, session_removed_at: uh2End)

      ranges = LessonSessionAnalyser.time_ranges [uh1, uh2]

      LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh2End)]
    end

    it "three overlapping times" do
      uh1Begin = start
      uh1End = start + 1

      uh2Begin = start + 0.5
      uh2End = start + 5

      uh3Begin = start + 0.1
      uh3End = start + 6

      uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
      uh2 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh2Begin, session_removed_at: uh2End)
      uh3 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh3Begin, session_removed_at: uh3End)

      ranges = LessonSessionAnalyser.time_ranges [uh1, uh2, uh3]

      LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh3End)]
    end
  end
end

=end