require './core/network_traffic_analytics/schema_validator'

# tier1_event_filtering.rb will filter HAR events for use in
# Tier 1 Video Player Event Validation.
class Tier1EventFiltering
  include RSpec::Matchers

  def initialize
    # Data provider for video-play events:
    # Key is the event: 'video-play'.
    # Value holds an array: [boolean, file path].
    # Boolean is set to false unless found in HAR.
    @video_play_event = {
      'video-play' => [false, '/video_player/tier1_events/video_play_event_schema']
    }

    # Data provider for minute-watched events:
    # Key is the event: 'minutes-watched'.
    # Value holds an array: [boolean, file path].
    # Boolean is set to false unless found in HAR.
    #
    # Note: 'm_w_2' is the same event as 'minutes-watched' but requires the
    # property key 'minutes_logged' to have the value '2'.
    @minute_watched_event = {
      'minute-watched' => [false, '/video_player/tier1_events/m_w_event_schema'],
      'm_w_2' => [false, '/video_player/tier1_events/m_w_event_schema']
    }

    # Data provider for buffer-empty events:
    # Key is the event: 'buffer-empty'.
    # Value holds an array: [boolean, file path].
    # Boolean is set to false unless found in HAR.
    @buffer_empty_event = {
      'buffer-empty' => [false, '/video_player/tier1_events/buffer_empty_schema']
    }

    # Data provider for buffer-empty events:
    # Key is the event: 'buffer-empty'.
    # Value holds an array: [boolean, file path].
    # Boolean is set to false unless found in HAR.
    @buffer_refill_event = {
      'buffer-refill' => [false, '/video_player/tier1_events/buffer_refill_schema']
    }
  end

  # Method to filter video-play events.
  # @param spade_events [Array] A collection of all entry bodies matching @@spade_url.
  # @return @@video_play_events [Hash] A collection of events that match the desired Video Player Tier 1 event.
  def get_video_play_event(spade_events)
    index = 0
    length = spade_events.size

    while index < length do
      event_name = spade_events[index][0]
      event_body = spade_events[index][1]

      @video_play_event.each do |key, value|

        if key == event_name

          # Check for duplicate events fired.
          if @video_play_event[event_name][0] == true
            puts "Event #{event_name} was fired more than once this test session. This could be due to page_reload event.\n"
            puts "\nAll collected spade events: #{spade_events}\n" # See Smoc-275
            puts "\nEvent Body: #{event_body}\n"

            if page_reload?(length, spade_events)
              @video_play_event[key][0] = true
            end
            puts "\nEvent: page_reload was found. Event: video-play fired successfully.\n"

          else
            @video_play_event[key][0] = true
            expect(event_body).to match_response_schema(@video_play_event[key][1])

            # Validate specifics by adding them to @@video_play_event hash.
            get_required_event_property_values(@video_play_event, key, event_body)
          end

        end

      end
      index += 1
    end
    return @video_play_event
  end

  # Method to filter minute-watched events.
  # @param spade_events [Array] A collection of all entry bodies matching @@spade_url.
  # @return @@minute_watched_event [Hash] A collection of events that match the desired Video Player Tier 1 event.
  def get_minute_watched_event(spade_events)
    index = 0
    length = spade_events.size

    while index < length do
      event_name = spade_events[index][0]
      event_body = spade_events[index][1]

      @minute_watched_event.each do |key, value|

        # Temp logging for SMOC-174 where minutes_logged returns a ridiculously
        # large value (ie. 3923). Issue has been non-reproducible
        # but keeps coming back sporadically.
        if event_body['properties']['minutes_logged'].to_i > 1000
          error_message("All collected spade events: #{spade_events}")
          error_message("Event Body: #{event_body}")
          fail("Event #{event_name} contains minutes_logged = #{event_body['properties']['minutes_logged']}.")
        end

        if key == event_name

          # Check for duplicate events fires. This test accepts minute-watched twice.
          # Second event should contain property minutes_logged => 2.
          if @minute_watched_event[event_name][0] == true

            if @minute_watched_event['m_w_2'][0] == false
              expect(event_body).to match_response_schema(@minute_watched_event['m_w_2'][1])
              @minute_watched_event['m_w_2'][0] = true

              # validate specifics by adding them to @@video_play_event hash.
              get_required_event_property_values(@minute_watched_event, 'm_w_2', event_body)

              # minutes-watched has an additonal required validation check
              @minute_watched_event['m_w_2'].push(event_body['properties']['minutes_logged'])
            else
              error_message("All collected spade events: #{spade_events}")
              error_message("Event Body: #{event_body}")
              fail("Event #{event_name} was fired more than twice this test session.")
            end
          else
            @minute_watched_event[key][0] = true
            expect(event_body).to match_response_schema(@minute_watched_event[key][1])

            # validate specifics by adding them to @@video_play_event hash.
            get_required_event_property_values(@minute_watched_event, key, event_body)

            # minutes-watched has an additonal required validation check
            @minute_watched_event[key].push(event_body['properties']['minutes_logged'])
          end
        end

      end
      index += 1
    end
    return @minute_watched_event
  end

  # Method to filter buffer-empty events.
  # @param spade_events [Array] A collection of all entry bodies matching @@spade_url.
  # @return @@buffer_empty_event [Hash] A collection of events that match the desired Video Player Tier 1 event.
  def get_buffer_empty_event(spade_events)
    index = 0
    length = spade_events.size

    while index < length do
      event_name = spade_events[index][0]
      event_body = spade_events[index][1]

      @buffer_empty_event.each do |key, value|

        if key == event_name

          # Check for duplicate events fired.
          if @buffer_empty_event[event_name][0] == true
            # We only need to captured the data of one of the buffer-empty events.
            break
          else
            @buffer_empty_event[key][0] = true
            expect(event_body).to match_response_schema(@buffer_empty_event[key][1])

            # Validate specifics by adding them to @@buffer_empty_event hash.
            get_required_event_property_values(@buffer_empty_event, key, event_body)
          end

        end

      end
      index += 1
    end
    return @buffer_empty_event
  end

  # Method to filter buffer-empty events.
  # @param spade_events [Array] A collection of all entry bodies matching @@spade_url.
  # @return @@buffer_empty_event [Hash] A collection of events that match the desired Video Player Tier 1 event.
  def get_buffer_refill_event(spade_events)
    index = 0
    length = spade_events.size

    while index < length do
      event_name = spade_events[index][0]
      event_body = spade_events[index][1]

      @buffer_refill_event.each do |key, value|

        if key == event_name

          # Check for duplicate events fired.
          if @buffer_refill_event[event_name][0] == true
            # We only need to captured the data of one of the buffer-refill events.
            break
          else
            @buffer_refill_event[key][0] = true
            expect(event_body).to match_response_schema(@buffer_refill_event[key][1])

            # Validate specifics by adding them to @@buffer_empty_event hash.
            get_required_event_property_values(@buffer_refill_event, key, event_body)
          end

        end

      end
      index += 1
    end

    return @buffer_refill_event
  end

  # Method to get specific required video player event values.
  # @param event_hash [Hash] The data provider at the start of the test: @@video_play_event or @@minute_watched_event
  # @param key [String] The Tier 1 video player event that was found: video-play, minutes_watched
  # @param event_body [Hash] The json body of the specific Tier 1 video player event.
  private def get_required_event_property_values(event_hash, key, event_body)
    event_hash[key].push(event_body['properties']['url'])
    event_hash[key].push(event_body['properties']['host'])
    event_hash[key].push(event_body['properties']['domain'])
    event_hash[key].push(event_body['properties']['channel'])
  end

  private def page_reload?(length, spade_events)
    index = 0
    # If the player discovers a backend error the page will reload, and this can
    # cause a duplicate event.
    while index < length do
      event_name = spade_events[index][0]

      if event_name == 'page_reload'
        return true
      end
      index += 1
    end
    return false
  end

end
