require 'musicbrainz'
require 'discogs'
require 'nokogiri'
require 'zlib'

class ImportController < ApplicationController
  def self.importArtist name, dry_run = false
    artist = Artist.find_or_create_by_name(name)
    return 3 if artist.status == 1
    
    begin
      lastfm_artist = LastFM::Artist.get_info( :artist => name )
      unless artist.mbid.nil? or artist.mbid.empty?
        brainz_artist = MusicBrainz::Artist.find(artist.mbid)
      else
        brainz_artist = MusicBrainz::Artist.find_by_name(name)
      end
    rescue => e
      lastfm_artist = { 'artist' => {
        'bio' => { 'summary' => '' },
        'image' => [ nil, nil, nil, { '#text' => '' } ],
        'stats' => { 'listeners' => 0 }
      } }
      ap e.message
      ap e.backtrace
    end
    
    if brainz_artist.nil?
      artist.mbid = nil
      artist.status = 2
      artist.save
      return 2
    end

    begin
      # Save artist
      artist.desc = lastfm_artist['artist']['bio']['summary']
      artist.pic_url = lastfm_artist['artist']['image'][3]['#text']
      artist.listeners = lastfm_artist['artist']['stats']['listeners']
      artist.artist_type = brainz_artist.type
      artist.mbid = brainz_artist.id
      artist.save
      
      brainz_artist.urls.each do |service, url|
        ArtistLink.new(
          :artist_id => artist.id,
          :service => service.to_s,
          :url => url
        ).save
      end
      
      unless brainz_artist.urls[:discogs].nil?
        Discogs.get_master_albums(brainz_artist.urls[:discogs]).each do |info|
          begin
            puts "  * "+info[:title]+" ("+info[:year]+") -- http://api.discogs.com/"+info[:uri]+")"
            stream = open("http://api.discogs.com/"+info[:uri]+"?f=xml",
              'User-Agent' => 'Haven Import Bot',
              'Accept-Encoding' => 'gzip, deflate'
            )
            if (stream.content_encoding.empty?)
              body = stream.read
            else
              body = Zlib::GzipReader.new(stream).read
            end
            # Creating album
            album = Album.new(
              :name => info[:title],
              :artist_id => artist.id,
              :year => info[:year],
              :status => 1,
              :master => true
            )
            begin
              album_lastfm = LastFM::Album.get_info( :artist => lastfm_artist['artist']['name'], :album => info[:title] )
              album_image = album_lastfm['album']['image'][3]['#text']
            rescue
              album_image = ''
            end
            album.pic_url = album_image
            album.has_pic = (album_image != '' and not album_image.nil?)
            album.save
            Discogs.save_album(artist, album, Nokogiri::HTML(body))
          end
          sleep 1
        end
      end
           
      # brainz_artist.release_groups.each do |brainz_release_group|
      #   # Saving album
      #   begin
      #     album_lastfm = LastFM::Album.get_info( :artist => lastfm_artist['artist']['name'], :album => '' )
      #     album_image = album_lastfm['album']['image'][3]['#text']
      #   rescue
      #     album_image = ''
      #   end
      #   album = Album.new
      #   album.name = brainz_release_group.title
      #   album.year = brainz_release_group.first_release_date.year
      #   album.artist_id = artist.id
      #   album.mbid = brainz_release_group.id
      #   album.album_type = brainz_release_group.type
      #   album.pic_url = album_image
      #   album.has_pic = (album_image != '' and not album_image.nil?)
      #   album.status = 0
      #   album.save
      #   # Tracks from the first release
      #   tracks_hashed = []
      #   brainz_release_group.releases.each_with_index do |brainz_release, i|
      #     local_brainz_release = LocalBrainz::Release.new(
      #       :mbid => brainz_release.id,
      #       :title => brainz_release.title,
      #       :status => brainz_release.status,
      #       :date => brainz_release.date,
      #       :country => brainz_release.country,
      #       :format => brainz_release.format,
      #       :album_id => album.id
      #     )
      #     local_brainz_release.save
      #     # Processing tracks
      #     brainz_release.tracks.each do |brainz_track|
      #       local_brainz_track = LocalBrainz::Track.new(
      #         :position => brainz_track.position,
      #         :recording_id => brainz_track.recording_id,
      #         :title => brainz_track.title,
      #         :length => brainz_track.length,
      #         :release_id => local_brainz_release.id
      #       )
      #       local_brainz_track.save
      #       track_title = brainz_track.title.gsub(/\s\/\s\[.*?\]/, '')
      #       if tracks_hashed.include? track_title.downcase.scan(/[a-z0-9]*/).join
      #         next
      #       end
      #       tracks_hashed << track_title.downcase.scan(/[a-z0-9]*/).join
      #       track = Track.new
      #       track.name = track_title
      #       track.album_id = album.id
      #       track.position = brainz_track.position
      #       track.length = brainz_track.length
      #       track.country = brainz_release.country
      #       track.bonus = (i == 0 ? 0 : 1)
      #       track.live = track_title.downcase.include? 'live'
      #       track.acoustic = track_title.downcase.include? 'acoustic'
      #       track.mbid = brainz_track.recording_id
      #       track.save
      #     end
      #   end
      #   album.status = 1
      #   album.save unless dry_run
      # end
       
      artist.status = 1
    rescue => e
      ap e.message
      ap e.backtrace
      artist.status = 2
    end
    
    artist.save unless dry_run
    artist.status
  end
  
  def self.parseLastfmXML path
    Nokogiri::XML(open(path)).css('lfm > artists > artist').map do |node|
      artist = {}
      artist[:name] = node.css('name').text
      artist[:mbid] = nil
      artist[:mbid] = node.css('mbid').text unless node.css('mbid').empty?
      artist
    end
  end
  
end