namespace :i18n do
  task "common" do
    require 'yaml'
    begin
      require 'social_stream/components'
    rescue LoadError
      # Use this task from social_stream global gem
      # (which defines social_stream/components),
      # as well as from any application using social_stream-base
    end

    @engines = [ '.' ]

    if defined? SocialStream::ALL_COMPONENTS
      @engines += SocialStream::ALL_COMPONENTS
    end
  end

  desc "Synchronize i18n files"
  task "sync" => "common" do
    Hash.class_eval do
      def sync(h)
        en_hash = h.dup

        each_key do |self_key|
          en_val = en_hash.delete(self_key)

          case en_val
          when NilClass
            delete(self_key)
          when Hash
            if self[self_key].is_a?(Hash)
              self[self_key].sync(en_val)
            else
              self[self_key] = en_val
            end
          when String
            if self[self_key].nil?
              self[self_key] = en_val
            end
          else
            raise "Unknown key type #{ en_val.inspect }"
          end
        end

        # Merge missing keys
        merge! en_hash

        # Order alphabetically
        replace sort_by{ |k, v| k }.inject({}){ |h, a| h[a.first] = a.last; h }
      end
    end


    @engines.each do |c|
      path = "#{ c }/config/locales/"

      files = Dir[path + '*'].select{ |f| f =~ /\/\w+\.yml$/ }

      en = files.find{ |f| f =~ /\/en.yml$/ }
      files.delete(en)

      en_h = Psych.load_file(en)

      files.each do |f|
        h = Psych.load_file(f)

        # Leave language_name at the begining of the hash
        if c == "base"
          orig_h = h.first.last
          orig_en_h = en_h.first.last.dup

          language_name = orig_h.delete('language_name')
          language_name_en = orig_en_h.delete('language_name')
          language_name ||= language_name_en 

          orig_h.sync orig_en_h

          h.first.last.replace({ 'language_name' => language_name }.merge!(orig_h))
        else
          h.first.last.sync en_h.first.last
        end

        Psych.dump h, File.open(f, 'w')
      end

      Psych.dump en_h, File.open(en, 'w')
    end
  end

  desc "Write missing keys of i18n files"
  task "diff" => "common" do
    Hash.class_eval do
      def diff(en_hash)
        diff_hash = {}
        
        en_hash.each_key do |en_key|
          en_val   = en_hash[en_key]
          self_val = self[en_key]

          case en_val
          when NilClass
            # Do nothing
          when Hash
            if self_val.is_a?(Hash)
              diff = self_val.diff(en_val)

              if !diff.empty?
                diff_hash[en_key] = diff
              end
            else
              en_val.each do |key, value|
                if value.class == Hash
                  puts "hola"
                else
                  value += "foo \nbar"
                end
                en_val[key] = value
              end
              diff_hash[en_key] = en_val
            end
          when String
            if self_val.nil? || self_val == en_val
              diff_hash[en_key] = en_val + "foo \nbar"
            end
          else
            raise "Unknown key type #{ en_val.inspect }"
          end          
        end

        diff_hash
      end
    end

    @engines.each do |c|
      path = "#{ c }/config/locales/"

      files = Dir[path + '*'].select{ |f| f =~ /\/\w+\.yml$/ }

      en = files.find{ |f| f =~ /\/en.yml$/ }
      files.delete(en)

      en_h = Psych.load_file(en)

      files.each do |f|
        h = Psych.load_file(f)        
        puts "START WITH LOCALE " + f
        diff_hash = h.first.last.diff en_h.first.last

        if !diff_hash.empty?
          puts "DIFFERENCES IN LOCALE, WRITTING TO FILE "+ f + ".diff"
          Psych.dump(diff_hash, File.open("#{ f }.diff", 'wb'), line_width: -1)
        end
      end
    end
  end
end
