require 'recaptcha'
class
MusicSessionManager < BaseManager

  include Recaptcha::Verify
  
  def initialize(options={})
    super(options)
    @log = Logging.logger[self]
  end

  def create(user, client_id, description, musician_access, approval_required, fan_chat, fan_access, band, genres, tracks, legal_terms)
    return_value = nil

    ActiveRecord::Base.transaction do
      # check if we are connected to rabbitmq
      music_session = MusicSession.new()
      music_session.creator = user
      music_session.description = description
      music_session.musician_access = musician_access
      music_session.approval_required = approval_required
      music_session.fan_chat = fan_chat
      music_session.fan_access = fan_access
      music_session.band = band
      music_session.legal_terms = legal_terms

      #genres = genres
      @log.debug "Genres class: " + genres.class.to_s()

      unless genres.nil?
        genres.each do |genre_id|
          loaded_genre = Genre.find(genre_id)
          music_session.genres << loaded_genre
        end
      end

      music_session.save

      unless music_session.errors.any?
        # save session parameters for next session
        User.save_session_settings(user, music_session)

        # save session history
        MusicSessionHistory.save(music_session)
        
        # auto-join this user into the newly created session
        as_musician = true
        connection = ConnectionManager.new.join_music_session(user, client_id, music_session, as_musician, tracks)  do |db_conn, connection|
          if as_musician && music_session.musician_access
            Notification.send_musician_session_join(music_session, connection, user)
            Notification.send_friend_session_join(db_conn, connection, user)
          end
        end

        unless connection.errors.any?
          return_value = music_session
        else
          return_value = connection
          # rollback the transaction to make sure nothing is disturbed in the database
          raise ActiveRecord::Rollback
        end
      else
        return_value = music_session
        # rollback the transaction to make sure nothing is disturbed in the database
        raise ActiveRecord::Rollback
      end
    end

    return return_value
  end

  # Update the session. If a field is left out (meaning, it's set to nil), it's not updated.
  def update(music_session, description, genres, musician_access, approval_required, fan_chat, fan_access)

    update = {}
    update[:description] = description unless description.nil?
    update[:musician_access] = musician_access unless musician_access.nil?
    update[:approval_required] = approval_required unless approval_required.nil?
    update[:fan_chat] = fan_chat unless fan_chat.nil?
    update[:fan_access] = fan_access unless fan_access.nil?
    # Do I have to do this the way he did above? Not sure. Probably yes.
    genre_array = []
    if genres.nil?
      music_session.skip_genre_validation = true
    else
      genres.each do |genre_id|
        loaded_genre = Genre.find(genre_id)
        genre_array << loaded_genre
      end
      update[:genres] = genre_array
    end

    if music_session.update_attributes(update)
      # save session history (only thing that could change is description)
      MusicSessionHistory.save(music_session)
    end

    return music_session
  end

  def participant_create(user, music_session_id, client_id, as_musician, tracks)
    connection = nil
    ActiveRecord::Base.transaction do

      music_session = MusicSession.find(music_session_id)

      connection = ConnectionManager.new.join_music_session(user, client_id, music_session, as_musician, tracks)  do |db_conn, connection|
        if as_musician && music_session.musician_access
          Notification.send_musician_session_join(music_session, connection, user)
          Notification.send_friend_session_join(db_conn, connection, user)
        end
      end

      if connection.errors.any?
        # rollback the transaction to make sure nothing is disturbed in the database
        raise ActiveRecord::Rollback
      else
        # send out notification to queue to the rest of the session
        # TODO: also this isn't necessarily a user leaving; it's a client leaving'
      end
    end

    return connection
  end
  
  def participant_delete(user, connection, music_session)
    
    if connection.user.id != user.id
      raise PermissionError, "you do not own this connection"
    end

    ConnectionManager.new.leave_music_session(user, connection, music_session) do
      Notification.send_musician_session_depart(music_session, connection.client_id, user)
    end

    unless music_session.nil?
      # send out notification to queue to the rest of the session
      # TODO: we should rename the notification to music_session_participants_change or something
      # TODO: also this isn't necessarily a user leaving; it's a client leaving
    end
  end
end
