require "rails_helper"
require "i18n/duplicate_key_finder"

def extract_locale(path)
  path[/\.([^.]{2,})\.yml$/, 1]
end

PLURALIZATION_KEYS ||= ['zero', 'one', 'two', 'few', 'many', 'other']

def find_pluralizations(hash, parent_key = '', pluralizations = Hash.new)
  hash.each do |key, value|
    if Hash === value
      current_key = parent_key.blank? ? key : "#{parent_key}.#{key}"
      find_pluralizations(value, current_key, pluralizations)
    elsif PLURALIZATION_KEYS.include? key
      pluralizations[parent_key] = hash
    end
  end

  pluralizations
end

def is_yaml_compatible?(english, translated)
  english.each do |k, v|
    if translated.has_key?(k)
      if Hash === v
        if Hash === translated[k]
          return false unless is_yaml_compatible?(v, translated[k])
        end
      else
        return false unless v.class == translated[k].class
      end
    end
  end

  true
end

describe "i18n integrity checks" do

  it 'has an i18n key for each Trust Levels' do
    TrustLevel.all.each do |ts|
      expect(ts.name).not_to match(/translation missing/)
    end
  end

  it "has an i18n key for each Site Setting" do
    SiteSetting.all_settings.each do |s|
      next if s[:setting][/^test_/]
      expect(s[:description]).not_to match(/translation missing/)
    end
  end

  it "has an i18n key for each Badge description" do
    Badge.where(system: true).each do |b|
      expect(b.long_description).to be_present
      expect(b.description).to be_present
    end
  end

  Dir["#{Rails.root}/config/locales/{client,server}.*.yml"].each do |path|
    it "does not contain invalid interpolation keys for '#{path}'" do
      matches = File.read(path).scan(/%\{([^a-zA-Z\s]+)\}|\{\{([^a-zA-Z\s]+)\}\}/)
      matches.flatten!
      matches.compact!
      matches.uniq!
      expect(matches).to eq([])
    end
  end

  Dir["#{Rails.root}/config/locales/client.*.yml"].each do |path|
    it "has valid client YAML for '#{path}'" do
      yaml = YAML.load_file(path)
      locale = extract_locale(path)

      expect(yaml.keys).to eq([locale])

      expect(yaml[locale]["js"]).to be
      expect(yaml[locale]["admin_js"]).to be
      # expect(yaml[locale]["wizard_js"]).to be
    end
  end

  Dir["#{Rails.root}/**/locale*/*.en.yml"].each do |english_path|
    english_yaml = YAML.load_file(english_path)["en"]

    context(english_path) do
      it "has no duplicate keys" do
        english_duplicates = DuplicateKeyFinder.new.find_duplicates(english_path)
        expect(english_duplicates).to be_empty
      end

      find_pluralizations(english_yaml).each do |key, hash|
        next if key["messages.restrict_dependent_destroy"]

        it "has valid pluralizations for '#{key}'" do
          expect(hash.keys).to contain_exactly("one", "other")
        end
      end
    end

    Dir[english_path.sub(".en.yml", ".*.yml")].each do |path|
      next if path[".en.yml"]

      context(path) do
        locale = extract_locale(path)
        yaml = YAML.load_file(path)

        it "has no duplicate keys" do
          duplicates = DuplicateKeyFinder.new.find_duplicates(path)
          expect(duplicates).to be_empty
        end

        it "does not overwrite another locale" do
          expect(yaml.keys).to eq([locale])
        end

        unless path["transliterate"]

          it "is compatible with english" do
            expect(is_yaml_compatible?(english_yaml, yaml)).to eq(true)
          end

        end

      end

    end
  end

end