// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2007-2014, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.format;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.CurrencyPluralInfo;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.PluralFormat;
import com.ibm.icu.util.ULocale;

/**
 * @author tschumann (Tim Schumann)
 *
 */
@RunWith(JUnit4.class)
public class PluralFormatTest extends TestFmwk {
  private void helperTestRules(String localeIDs, String testPattern, Map<Integer,String> changes) {
    String[] locales = Utility.split(localeIDs, ',');

    // Create example outputs for all supported locales.
    /*
    System.out.println("\n" + localeIDs);
    String lastValue = (String) changes.get(new Integer(0));
    int  lastNumber = 0;

    for (int i = 1; i < 199; ++i) {
        if (changes.get(new Integer(i)) != null) {
            if (lastNumber == i-1) {
                System.out.println(lastNumber + ": " + lastValue);
            } else {
                System.out.println(lastNumber + "... " + (i-1) + ": " + lastValue);
            }
            lastNumber = i;
            lastValue = (String) changes.get(new Integer(i));
        }
    }
    System.out.println(lastNumber + "..." + 199 + ": " + lastValue);
    */
    log("test pattern: '" + testPattern + "'");
    for (int i = 0; i < locales.length; ++i) {
      try {
        PluralFormat plf = new PluralFormat(new ULocale(locales[i]), testPattern);
        log("plf: " + plf);
        String expected = changes.get(new Integer(0));
        for (int n = 0; n < 200; ++n) {
          String value = changes.get(n);
          if (value != null) {
            expected = value;
          }
          assertEquals("Locale: " + locales[i] + ", number: " + n,
                       expected, plf.format(n));
        }
      } catch (IllegalArgumentException e) {
        errln(e.getMessage() + " locale: " + locales[i] + " pattern: '" + testPattern + "' " + System.currentTimeMillis());
      }
    }
  }

  @Test
  public void TestOneFormLocales() {
    String localeIDs = "ja,ko,tr,vi";
    String testPattern = "other{other}";
    Map changes = new HashMap();
    changes.put(new Integer(0), "other");
    helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestSingular1Locales() {
    String localeIDs = "bem,da,de,el,en,eo,es,et,fi,fo,he,it,mr,nb,nl,nn,no,pt_PT,sv,af,bg,ca,eu,fur,fy,ha,ku,lb,ml," +
        "nah,ne,om,or,pap,ps,so,sq,sw,ta,te,tk,ur,mn,gsw,rm";
    String testPattern = "one{one} other{other}";
    Map changes = new HashMap();
    changes.put(new Integer(0), "other");
    changes.put(new Integer(1), "one");
    changes.put(new Integer(2), "other");
    helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestSingular01Locales() {
    String localeIDs = "ff,fr,kab,gu,pa,pt,zu,bn";
    String testPattern = "one{one} other{other}";
    Map changes = new HashMap();
    changes.put(new Integer(0), "one");
    changes.put(new Integer(2), "other");
    helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestZeroSingularLocales() {
    String localeIDs = "lv";
    String testPattern = "zero{zero} one{one} other{other}";
    Map changes = new HashMap();
    changes.put(new Integer(0), "zero");
    changes.put(new Integer(1), "one");
    for (int i = 2; i < 20; ++i) {
      if (i < 10) {
        changes.put(new Integer(i), "other");
      } else {
        changes.put(new Integer(i), "zero");
      }
      changes.put(new Integer(i*10), "zero");
      if (i == 11) {
        changes.put(new Integer(i*10 + 1), "zero");
        changes.put(new Integer(i*10 + 2), "zero");
      } else {
        changes.put(new Integer(i*10 + 1), "one");
        changes.put(new Integer(i*10 + 2), "other");
      }
    }
    helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestSingularDual() {
      String localeIDs = "ga";
      String testPattern = "one{one} two{two} other{other}";
      Map changes = new HashMap();
      changes.put(new Integer(0), "other");
      changes.put(new Integer(1), "one");
      changes.put(new Integer(2), "two");
      changes.put(new Integer(3), "other");
      helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestSingularZeroSome() {
      String localeIDs = "ro";
      String testPattern = "few{few} one{one} other{other}";
      Map changes = new HashMap();
      changes.put(new Integer(0), "few");
      changes.put(new Integer(1), "one");
      changes.put(new Integer(2), "few");
      changes.put(new Integer(20), "other");
      changes.put(new Integer(101), "other");
      changes.put(new Integer(102), "few");
      changes.put(new Integer(120), "other");
      helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestSpecial12_19() {
      String localeIDs = "lt";
      String testPattern = "one{one} few{few} other{other}";
      Map changes = new HashMap();
      changes.put(new Integer(0), "other");
      changes.put(new Integer(1), "one");
      changes.put(new Integer(2), "few");
      changes.put(new Integer(10), "other");
      for (int i = 2; i < 20; ++i) {
        if (i == 11) {
          continue;
        }
        changes.put(new Integer(i*10 + 1), "one");
        changes.put(new Integer(i*10 + 2), "few");
        changes.put(new Integer((i+1)*10), "other");
      }
      helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestPaucalExcept11_14() {
      String localeIDs = "hr,sr,uk";
      String testPattern = "one{one} few{few} other{other}";
      Map changes = new HashMap();
      changes.put(new Integer(0), "other");
      changes.put(new Integer(1), "one");
      changes.put(new Integer(2), "few");
      changes.put(new Integer(5), "other");
      for (int i = 2; i < 20; ++i) {
        if (i == 11) {
          continue;
        }
        changes.put(new Integer(i*10 + 1), "one");
        changes.put(new Integer(i*10 + 2), "few");
        changes.put(new Integer(i*10 + 5), "other");
      }
      helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestPaucalRu() {
      String localeIDs = "ru";
      String testPattern = "one{one} many{many} other{other}";
      Map changes = new HashMap();
      for (int i = 0; i < 200; i+=10) {
          if (i == 10 || i == 110) {
              put(i, 0, 9, "many", changes);
              continue;
          }
          put(i, 0, "many", changes);
          put(i, 1, "one", changes);
          put(i, 2, 4, "other", changes);
          put(i, 5, 9, "many", changes);
      }
      helperTestRules(localeIDs, testPattern, changes);
  }

  public <T> void put(int base, int start, int end, T value, Map<Integer, T> m) {
      for (int i = start; i <= end; ++i) {
          if (m.containsKey(base + i)) {
              throw new IllegalArgumentException();
          }
          m.put(base + i, value);
      }
  }

  public <T> void put(int base, int start, T value, Map<Integer, T> m) {
      put(base, start, start, value, m);
  }

  @Test
  public void TestSingularPaucal() {
      String localeIDs = "cs,sk";
      String testPattern = "one{one} few{few} other{other}";
      Map changes = new HashMap();
      changes.put(new Integer(0), "other");
      changes.put(new Integer(1), "one");
      changes.put(new Integer(2), "few");
      changes.put(new Integer(5), "other");
      helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestPaucal1_234() {
      String localeIDs = "pl";
      String testPattern = "one{one} few{few} other{other}";
      Map changes = new HashMap();
      changes.put(new Integer(0), "other");
      changes.put(new Integer(1), "one");
      changes.put(new Integer(2), "few");
      changes.put(new Integer(5), "other");
      for (int i = 2; i < 20; ++i) {
        if (i == 11) {
          continue;
        }
        changes.put(new Integer(i*10 + 2), "few");
        changes.put(new Integer(i*10 + 5), "other");
      }
      helperTestRules(localeIDs, testPattern, changes);
  }

  @Test
  public void TestPaucal1_2_34() {
      String localeIDs = "sl";
      String testPattern = "one{one} two{two} few{few} other{other}";
      Map changes = new HashMap();
      changes.put(new Integer(0), "other");
      changes.put(new Integer(1), "one");
      changes.put(new Integer(2), "two");
      changes.put(new Integer(3), "few");
      changes.put(new Integer(5), "other");
      changes.put(new Integer(101), "one");
      changes.put(new Integer(102), "two");
      changes.put(new Integer(103), "few");
      changes.put(new Integer(105), "other");
      helperTestRules(localeIDs, testPattern, changes);
  }

    /* Tests the method public PluralRules getPluralRules() */
    @Test
    public void TestGetPluralRules() {
        CurrencyPluralInfo cpi = new CurrencyPluralInfo();
        try {
            cpi.getPluralRules();
        } catch (Exception e) {
            errln("CurrencyPluralInfo.getPluralRules() was not suppose to " + "return an exception.");
        }
    }

    /* Tests the method public ULocale getLocale() */
    @Test
    public void TestGetLocale() {
        CurrencyPluralInfo cpi = new CurrencyPluralInfo(new ULocale("en_US"));
        if (!cpi.getLocale().equals(new ULocale("en_US"))) {
            errln("CurrencyPluralInfo.getLocale() was suppose to return true " + "when passing the same ULocale");
        }
        if (cpi.getLocale().equals(new ULocale("jp_JP"))) {
            errln("CurrencyPluralInfo.getLocale() was not suppose to return true " + "when passing a different ULocale");
        }
    }

    /* Tests the method public void setLocale(ULocale loc) */
    @Test
    public void TestSetLocale() {
        CurrencyPluralInfo cpi = new CurrencyPluralInfo();
        cpi.setLocale(new ULocale("en_US"));
        if (!cpi.getLocale().equals(new ULocale("en_US"))) {
            errln("CurrencyPluralInfo.setLocale() was suppose to return true when passing the same ULocale");
        }
        if (cpi.getLocale().equals(new ULocale("jp_JP"))) {
            errln("CurrencyPluralInfo.setLocale() was not suppose to return true when passing a different ULocale");
        }
    }

    /* Tests the method public boolean equals(Object a) */
    @Test
    public void TestEquals(){
        CurrencyPluralInfo cpi = new CurrencyPluralInfo();
        if(cpi.equals(0)){
            errln("CurrencyPluralInfo.equals(Object) was not suppose to return true when comparing to an invalid object for integer 0.");
        }
        if(cpi.equals(0.0)){
            errln("CurrencyPluralInfo.equals(Object) was not suppose to return true when comparing to an invalid object for float 0.");
        }
        if(cpi.equals("0")){
            errln("CurrencyPluralInfo.equals(Object) was not suppose to return true when comparing to an invalid object for string 0.");
        }
    }

    /* Test for http://bugs.icu-project.org/trac/ticket/13151 */
    @Test
    public void TestFractionRounding() {
        NumberFormat nf = NumberFormat.getInstance(Locale.ENGLISH);
        nf.setMaximumFractionDigits(0);
        PluralFormat pf = new PluralFormat(ULocale.ENGLISH, "one{#kg}other{#kgs}");
        pf.setNumberFormat(nf);
        assertEquals("1.2kg", "1kg", pf.format(1.2));
    }
}
