require 'resque'

# more info on Measurement Protocol https://developers.google.com/analytics/devguides/collection/protocol/v1/
module JamRuby
  class GoogleAnalyticsEvent
    extend ResqueStats

    @queue = :google_analytics_event

    CAT_SESS_SIZE = 'SessionSize'
    ACTION_SESS_SIZE = 'Size'
    CAT_SESS_DUR = 'SessionDuration'
    ACTION_SESS_DUR = 'Duration'
    CAT_BAND = 'Band'
    ACTION_BAND_SESS = 'Session'
    ACTION_BAND_REC = 'Recording'

    @@log = Logging.logger[GoogleAnalyticsEvent]

    SESSION_INTERVALS = [1, 5, 10, 15, 30, 45, 60, 90, 120, 180]  # minutes
    QUEUE_BAND_TRACKER = :band_tracker
    QUEUE_SESSION_TRACKER = :session_tracker

    class SessionDurationTracker
      @queue = QUEUE_SESSION_TRACKER

      def self.perform(args={})
        session_id, interval_idx = args['session_id'], args['interval_idx'].to_i
        return unless session_id && session = MusicSession.find_by_id(session_id)
        GoogleAnalyticsEvent.enqueue(CAT_SESS_DUR, ACTION_SESS_DUR, SESSION_INTERVALS[interval_idx])
        interval_idx += 1
        
        if SESSION_INTERVALS.count-1 > interval_idx
          next_time = session.created_at + SESSION_INTERVALS[interval_idx].minutes
          Resque.enqueue_at(next_time, self, :session_id => session_id, :interval_idx => interval_idx)
        end
      end
    end

    def self.track_session_duration(session)
      Resque.enqueue_at(SESSION_INTERVALS[0].minute.from_now, 
                        SessionDurationTracker, 
                        :session_id => session.id, 
                        :interval_idx => 0)
    end

    class BandSessionTracker
      @queue = QUEUE_BAND_TRACKER

      def self.perform(session_id)
        return unless session = ActiveMusicSession.find(session_id)
        band = session.band
        if band.in_real_session?(session)
          band.update_attribute(:did_real_session, true)
          GoogleAnalyticsEvent.enqueue(CAT_BAND, ACTION_BAND_SESS, nil)
        end if band
      end
    end

    BAND_SESSION_MIN_DURATION = 15  # minutes

    def self.track_band_real_session(session)
      if session.band && !session.band.did_real_session?
        Resque.enqueue_at(BAND_SESSION_MIN_DURATION.minutes.from_now,
                          BandSessionTracker, 
                          session.id)
      end
    end

    def self.report_band_recording(band)
      if band && 1 == Recording.where(:band_id => band.id).count
        self.enqueue(CAT_BAND, ACTION_BAND_REC)
      end
    end

    def self.report_session_participant(participant_count)
      self.enqueue(CAT_SESS_SIZE, ACTION_SESS_SIZE, participant_count)
    end

    def self.enqueue(category, event, data=nil)
      begin
        Resque.enqueue(GoogleAnalyticsEvent, category, event, data)
        true
      rescue
        # implies redis is down.  but since there is no retry logic with this, we should at least log a warn in case we've configured something wrong
        @@log.warn("unable to enqueue")
        false
      end
    end

    def self.perform(category, action, data)
      @@log.info("starting (#{category}, #{action})")
      raise "no google analytics tracking ID" unless APP_CONFIG.ga_ua
      params = {
        v: APP_CONFIG.ga_ua_version,
        tid: APP_CONFIG.ga_ua,
        cid: APP_CONFIG.ga_anonymous_client_id,
        t: "event",
        ec: category,
        ea: action,
        el: 'data',
        ev: data.to_s
      }

      RestClient.post(APP_CONFIG.ga_endpoint, params: params, timeout: 8, open_timeout: 8)

      @@log.info("done (#{category}, #{action})")
    end

  end
end
