require 'lastfm'
require 'musicbrainz'

class ImportController < ApplicationController
  
  @@user_agent = 'BeatHaven.org'
  
  @@lastfm_api_key = '04fda005dbf61a50af5abc3e90f111f2'
  @@lastfm_secret = '19e70e98b291e9f15d0516925945eb1b'
  
  @@brainz_login = 'magnolia_fan'
  @@brainz_password = '111111'
  
  def self.importArtist name, dry_run = false
    
    # Initializing gems
    brainz = MusicBrainz::Client.new(@@brainz_login, @@brainz_password, @@user_agent)
    lastfm = Lastfm.new(@@lastfm_api_key, @@lastfm_secret)
    
    artist = Artist.find_or_create_by_name(name)

    begin
    
      # Get artist info
      artist_mb_data = ArtistController.musicBrainzExactSearch(name).first
      begin
        artist_lastfm = lastfm.artist.get_info(name)
        artist_mb = brainz.artist(artist_mb_data[:mbid])
      rescue => e
        ap e.message
        ap e.backtrace
      end
    
      # Save artist
      artist.desc = artist_lastfm['bio']['summary']
      artist.pic_url = artist_lastfm['image'][3]['content']
      artist.artist_type = artist_mb['artist']['type']
      artist.mbid = artist_mb_data[:mbid]
    
      # Get albums from MB
      release_groups_mb = brainz.release_group(nil, :artist => artist_mb_data[:mbid], :limit => 500)
      
      unless release_groups_mb['release_group_list']['release_group'].nil?
        
        if release_groups_mb['release_group_list']['release_group'].is_a? Hash
          release_groups_mb['release_group_list']['release_group'] = [release_groups_mb['release_group_list']['release_group']]
        end
        
        release_groups_mb['release_group_list']['release_group'].each do |mb_album|
          
          album_name = mb_album['title'] + (mb_album['disambiguation'].nil? ? '' : ' ('+ mb_album['disambiguation'] +')')
      
          # Checking if there is already an album with the same name
          albums_db = Album.where(:artist_id => artist.id, :name => album_name, :album_type => mb_album['type'])
          
          # Get album releases from MB
          releases_mb = brainz.release(nil, {'release-group' => mb_album['id']})
        
          unless releases_mb['release_list']['release'].nil? or not albums_db.empty?
            
            releases_mb = releases_mb['release_list']['release']
          
            if releases_mb.is_a? Hash
              releases_mb = [releases_mb]
            end
          
            releases_mb.delete_if { |a| a['date'].nil? }
            
            unless releases_mb.empty?
            
              releases_mb.each do |release|
                if release['date'].length == 4
                  release['date'] += '-12-28'
                elsif release['date'].length == 7
                  release['date'] += '-28'
                end
              end
        
              # Sorting releases by date
              releases_mb.sort! { |a, b| a['date'].to_date <=> b['date'].to_date }
              main_release = releases_mb.shift
        
              # Get tracks from the first release and then exclude release
              tracks_mb = []
              tracks_mb_r = brainz.release(main_release['id'], {'inc' => 'recordings'})
            
              unless tracks_mb_r['release']['medium_list']['medium'].nil?
              
                tracks_mb_r = tracks_mb_r['release']['medium_list']['medium']
            
                if tracks_mb_r.is_a? Hash
                  if tracks_mb_r['track_list']['track'].is_a? Hash
                    tracks_mb_r['track_list']['track'] = [tracks_mb_r['track_list']['track']]
                  end
                  tracks_mb = tracks_mb_r['track_list']['track']
                elsif tracks_mb_r.is_a? Array
                  tracks_mb = tracks_mb_r.shift['track_list']['track']
                  tracks_mb_r.each do |cd|
                    if cd['track_list']['track'].is_a? Hash
                      cd['track_list']['track'] = [cd['track_list']['track']]
                    end
                    cd['track_list']['track'].each { |mb_track| mb_track['bonus'] = 1 }
                    tracks_mb |= cd['track_list']['track']
                  end
                end
        
                unless tracks_mb.empty?

                  # Saving album
                  begin
                    album_lastfm = lastfm.album.get_info(artist_lastfm['name'], album_name)
                    album_image = album_lastfm['image'][3]['content']
                  rescue
                    album_image = ''
                  end
          
                  album = Album.new
                  album.name = album_name
                  album.year = main_release['date'].to_date.year
                  album.artist_id = artist.id
                  album.mbid = mb_album['id']
                  album.album_type = mb_album['type']
                  album.pic_url = album_image
                  album.has_pic = (album_image != '' and not album_image.nil?)
                  album.save unless dry_run
                  ap album if dry_run
          
                  # Creating hashed array for matching
                  mb_main_tracks_hashed = []
                  tracks_mb.each do |mb_track|
                    unless mb_main_tracks_hashed.include? mb_track['recording']['title'].downcase.scan(/[a-z0-9]*/).join
                      mb_main_tracks_hashed << mb_track['recording']['title'].downcase.scan(/[a-z0-9]*/).join
                      mb_track['country'] = main_release['country'] unless main_release['country'].nil?
                      mb_track['bonus'] = 0 if mb_track['bonus'].nil?
                    end
                  end
          
                  # Searching for tracks in other releases
                  releases_mb.each do |mb_release|
            
                    other_tracks_mb = []
                    other_tracks_mb_r = brainz.release(mb_release['id'], {'inc' => 'recordings'})['release']['medium_list']['medium']
                    if other_tracks_mb_r.is_a? Hash
                      if other_tracks_mb_r['track_list']['track'].is_a? Hash
                        other_tracks_mb_r['track_list']['track'] = [other_tracks_mb_r['track_list']['track']]
                      end
                      other_tracks_mb = other_tracks_mb_r['track_list']['track']
                    elsif other_tracks_mb_r.is_a? Array
                      other_tracks_mb_r.each do |cd|
                        if cd['track_list']['track'].is_a? Hash
                          cd['track_list']['track'] = [cd['track_list']['track']]
                        end
                        other_tracks_mb |= cd['track_list']['track']
                      end
                    end
            
                    other_tracks_mb.each do |mb_track|
                      unless mb_main_tracks_hashed.include? mb_track['recording']['title'].downcase.scan(/[a-z0-9]*/).join
                        mb_track['country'] = mb_release['country'] unless mb_release['country'].nil?
                        mb_track['bonus'] = 1
                        tracks_mb << mb_track
                      end
                    end
                  end
          
                  # Saving tracks
                  tracks_mb.each do |mb_track|
                    unless ['[silence]', '[untitled]'].include? mb_track['recording']['title']
                      track = Track.new
                      track.name = mb_track['recording']['title'].gsub(/\s\\\s\[.*?\]/, '')
                      track.album_id = album.id
                      track.position = mb_track['position']
                      track.length = mb_track['length'] unless mb_track['length'].nil?
                      track.length = mb_track['recording']['length'] unless mb_track['recording']['length'].nil?
                      track.country = mb_track['country']
                      track.bonus = mb_track['bonus']
                      track.live = mb_track['recording']['title'].downcase.include? 'live'
                      track.acoustic = mb_track['recording']['title'].downcase.include? 'acoustic'
                      track.mbid = mb_track['recording']['id']
                      track.save unless dry_run
                    end
                  end
              
                end # unless tracks_mb_r['release']['medium_list']['medium'].nil?
              
              end # releases_mb.empty?
          
            end # unless mb_main_tracks.empty?
          
          end # unless releases_mb.nil?
      
        end # release_groups_mb.each do |mb_album|
        
      end # unless release_groups_mb['release_group_list']['release_group'].nil?
      
      artist.status = 1
      
    rescue => e
      ap e.message
      ap e.backtrace
      artist.status = 2
    end
    
    artist.save unless dry_run
    ap artist if dry_run
    
  end # def self.importArtist name
  
end