# -*- encoding : utf-8 -*-

module Phrase::Backend::Base
  
  def translate(*args)
    key = lookup_normalized_key(*args)
    case key[:translation]
      when String, nil, "" then decorate_translation(key[:key])
      else key[:translation]
    end
  end

  protected
    def decorate_translation(key=nil)
      return nil unless key.presence
      "#{Phrase.prefix}phrase_#{key}#{Phrase.suffix}"
    end

    def translation_presence(*args)
      I18n.translate!(*args)
    rescue I18n::MissingTranslationData => e
      nil
    end

    def lookup_normalized_key(*args)
      translation = translation_presence(*args)
      caller = identify_caller

      if (translation.nil? || translation.is_a?(Hash)) && caller && args.first =~ /^\./
        args = transform_args_for_caller(caller, *args)
        translation = translation_presence(*args)
      end

      new_args = split_args(*args)

      normalized_key = I18n::Backend::Flatten.normalize_flat_keys(*new_args)
      normalized_key.gsub!("..", ".")

      {:key => normalized_key, :translation => translation}
    end

    def identify_caller
      caller = nil
      send(:caller)[0..6].each { |string| caller = match_caller(string) unless caller }
      caller.present? ? find_lookup_scope(caller) : nil
    end

    def match_caller(string)
      string.match(/(views)(\/.+)(?>:[0-9]+:in)/)
    end

    def split_args(*args)
      options = args.last.is_a?(Hash) ? args.pop : {}
      key ||= args.shift
      locale = options.delete(:locale) || I18n.locale
      return [locale, key, options[:scope], nil]
    end

    def transform_args_for_caller(caller, *args)
      _scope = caller

      options = args.last.is_a?(Hash) ? args.pop : {}

      if !options[:scope].presence && _scope.presence
        options[:scope] = _scope
      end

      args.push(options)
      parts = args.first.to_s.split(".").select { |e| !e.blank? }
      args[0] = parts[0] if parts.size == 1

      return args
    end

    def find_lookup_scope(caller)
      split_path = caller[2][1..-1].split(".")[0].split("/")

      template_or_partial = remove_underscore_form_partial(split_path[-1])
      split_path[-1] = template_or_partial

      split_path.map!(&:to_sym)
    end

    def remove_underscore_form_partial(template_or_partial)
      if template_or_partial.to_s[0,1] == "_"
        template_or_partial.to_s[1..-1] 
      else
        template_or_partial.to_s
      end
    end
end