object @history

if !current_user
  # there should be more data returned, but we need to think very carefully about what data is public for a music session
  attributes :id

  child(:active_music_session => :active_music_session) {
    node do |music_session|
      child({:mount => :mount}, :if => lambda { |music_session| music_session.fan_access}) {
          attributes :id, :name, :sourced, :listeners, :bitrate, :subtype, :url
          node(:mime_type) { |mount|  mount.resolve_string(:mime_type) }
          node(:bitrate) { |mount|  mount.resolve_string(:bitrate) }
          node(:subtype) { |mount|  mount.resolve_string(:subtype) }
        }
    end
  }
else

  attributes :id, :music_session_id, :name, :description, :musician_access, :approval_required, :fan_access, :fan_chat,
   :band_id, :user_id, :genre_id, :created_at, :like_count, :comment_count, :play_count, :scheduled_duration,
   :language, :recurring_mode, :language_description, :scheduled_start_date, :access_description, :timezone, :timezone_id, :timezone_description,
   :musician_access_description, :fan_access_description, :session_removed_at, :legal_policy, :open_rsvps, :is_unstructured_rsvp?

  node :can_join do |session|
    session.can_join?(current_user, true)
  end

  node :share_url do |history|
    unless history.share_token.nil?
      share_token_url(history.share_token.token)
    end
  end

  node :genres do |item|
    [item.genre.description] # XXX: need to return single genre; not array
  end

  node :scheduled_start_date do |session|
    scheduled_start_date(session)
  end

  node :scheduled_start do |history|
    history.scheduled_start_time.strftime("%a %e %B %Y %H:%M:%S") if history.scheduled_start
  end

  node :pretty_scheduled_start_with_timezone do |session|
    pretty_scheduled_start(session, true)
  end

  node :pretty_scheduled_start_short do|session|
    pretty_scheduled_start(session, false)
  end

  child(:creator => :creator) {
    attributes :id, :name, :photo_url
  }

  child(:band => :band) {
    attributes :name, :photo_url
  }

  child(:music_session_user_histories => :users) {
    attributes :instruments, :user_id

    child(:user => :user) {
      attributes :id, :name, :photo_url
    }
  }

  child(:comments => :comments) {
    attributes :comment, :created_at

    child(:user => :creator) {
      attributes :id, :first_name, :last_name, :name, :photo_url, :musician
    }
  }

  child(:session_info_comments => :session_info_comments) {
    attributes :comment, :created_at

    child(:user => :creator) {
      attributes :id, :first_name, :last_name, :name, :photo_url, :musician
    }
  }

  child(:music_notations => :music_notations) {
      attributes :id, :file_name

      node do |music_notation|
        { file_url: "/api/music_notations/#{music_notation.id}",
          viewable: music_notation.music_session.can_join?(current_user, true) 
        }
      end
  }

  child({:invitations => :invitations}) {
    attributes :id, :sender_id, :receiver_id

    node do |invitation|
     user_score(invitation.receiver.id).merge({
       receiver_name: invitation.receiver.name,
       receiver_avatar_url: invitation.receiver.resolved_photo_url, 
       audio_latency: last_jam_audio_latency(invitation.receiver)
     })
    end
  }

  child({:approved_rsvps => :approved_rsvps}) {
    attributes :id, :photo_url, :first_name, :last_name, :name, :resolved_photo_url, :rsvp_request_id

    node do |user|
      user_score(user.id).merge({
        instrument_list: process_approved_rsvps(user),
        rsvp_request_id: JSON.parse(user.rsvp_request_ids)[0], # there must always be a rsvp_request_id; and they should all be the same
        audio_latency: last_jam_audio_latency(user)
      })
    end
  }

  child({:open_slots => :open_slots}) {
    attributes :id, :instrument_id, :proficiency_level, :proficiency_desc, :description
  }

  child({:pending_invitations => :pending_invitations}) {
    attributes :id, :email, :photo_url
  }

  child({:pending_rsvp_requests => :pending_rsvp_requests}) {
    attributes :id, :email, :photo_url, :user_id, :instrument_list

    child({:user => :user}) {
      attributes :id, :photo_url, :name, :first_name, :last_name

      node do |user|
        user_score(user.id).merge({
          name: user.name,
          audio_latency: last_jam_audio_latency(user)})
      end
    }
  }

  child(:active_music_session => :active_music_session) {
    attributes :claimed_recording_initiator_id, :track_changes_counter

    node :genres do |item|
      [item.genre.description] # XXX: need to return single genre; not array
    end

    if :is_recording?
        node do |music_session|
            { :recording => partial("api_recordings/show", :object => music_session.recording) }
        end
    end

    node :share_url do |music_session|
      unless music_session.music_session.share_token.nil?
        share_token_url(music_session.music_session.share_token.token)
      end
    end

    child(:connections => :participants) {
      collection @music_sessions, :object_root => false
      attributes :ip_address, :client_id, :joined_session_at

      node :user do |connection|
        user_score(connection.user.id).merge({
        :id => connection.user.id,
        :photo_url => connection.user.photo_url,
        :name => connection.user.name,
        :is_friend => connection.user.friends?(current_user),
        :connection_state => connection.aasm_state,
        audio_latency: last_jam_audio_latency(connection.user)})
      end

      child(:tracks => :tracks) {
          attributes :id, :connection_id, :instrument_id, :sound, :client_track_id, :client_resource_id, :updated_at
      }
    }

    # only show join_requests if the current_user is in the session
    node(:join_requests, :if => lambda { |music_session| music_session.users.exists?(current_user) } ) do |music_session|
      child(:join_requests => :join_requests) {
        attributes :id, :text
        child(:user => :user) {
            attributes :id, :name
        }
      }
    end

    # only show currently playing recording data if the current_user is in the session
    node(:claimed_recording, :if => lambda { |music_session| music_session.users.exists?(current_user) } ) do |music_session|

        child(:claimed_recording => :claimed_recording) {
            attributes :id, :name, :description, :is_public

            child(:recording => :recording) {
                attributes :id, :created_at, :duration
                child(:band => :band) {
                  attributes :id, :name
                }

                child(:mixes => :mixes) {
                  attributes :id, :is_completed

                  node :mp3_url do |mix|
                    mix[:mp3_url]
                  end

                  node :ogg_url do |mix|
                    mix[:ogg_url]
                  end
                }

                child(:recorded_tracks => :recorded_tracks) {
                    attributes :id, :fully_uploaded, :client_track_id, :client_id, :instrument_id

                    node :url do |recorded_track|
                      recorded_track[:url]
                    end

                    child(:user => :user) {
                      attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url
                    }
                }
            }
        }
    end

    # only show mount info if fan_access is public.  Eventually we'll also need to show this in other scenarios, like if invited
    child({:mount => :mount}, :if => lambda { |music_session| music_session.fan_access}) {
      attributes :id, :name, :sourced, :listeners, :bitrate, :subtype, :url
      node(:mime_type) { |mount|  mount.resolve_string(:mime_type) }
      node(:bitrate) { |mount|  mount.resolve_string(:bitrate) }
      node(:subtype) { |mount|  mount.resolve_string(:subtype) }
    }
  }
end