/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.i18n.server;

import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.i18n.shared.GwtLocaleFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Class representing GWT locales and conversion to/from other formats.
 * 
 * These locales correspond to BCP47.
 */
public class GwtLocaleImpl implements GwtLocale {
  // TODO(jat): implement a version of this suitable for client-side use,
  // probably using a generator to include only the information relevant to
  // the set of locales supported, and then figure out a way to get that into
  // the property provider to handle inheritance there.

  /**
   * Maps deprecated language codes to the canonical code.  Strings are always
   * in pairs, with the first being the canonical code and the second being
   * a deprecated code which maps to it.
   * <p>
   * Source: http://www.loc.gov/standards/iso639-2/php/code_changes.php
   * <p> 
   * TODO: consider building maps if this list grows much.
   */
  private static final String[] deprecatedLanguages = new String[] {
    "he", "iw",   // Hebrew
    "id", "in",   // Indonesian 
    "jv", "jw",   // Javanese, typo in original publication 
    "ro", "mo",   // Moldovian
    "yi", "ji",   // Yiddish
  };

  /**
   * Maps deprecated region codes to the canonical code.  Strings are always
   * in pairs, with the first being the canonical code and the second being
   * a deprecated code which maps to it.
   * 
   * Note that any mappings which split an old code into multiple new codes
   * cannot be done automatically (such as cs -> rs/me) -- perhaps we could
   * have a way of flagging region codes which are no longer valid and allow
   * an appropriate warning message.
   * <p>
   * Source: http://en.wikipedia.org/wiki/ISO_3166-1
   * <p>
   * TODO: consider building maps if this list grows much.
   */
  private static final String[] deprecatedRegions = new String[] {
    // East Timor - http://www.iso.org/iso/newsletter_v-5_east_timor.pdf
    "TL", "TP",
  };

  /**
   * Add in the missing locale of a deprecated pair.
   * 
   * @param factory GwtLocaleFactory to create new instances with
   * @param locale locale to add deprecated pair for
   * @param aliases where to store the alias if present
   */
  private static void addDeprecatedPairs(GwtLocaleFactory factory,
      GwtLocale locale, List<GwtLocale> aliases) {
    int n = deprecatedLanguages.length;
    for (int i = 0; i < n; i += 2) {
      if (deprecatedLanguages[i].equals(locale.getLanguage())) {
        aliases.add(factory.fromComponents(deprecatedLanguages[i + 1],
            locale.getScript(), locale.getRegion(), locale.getVariant()));
        break;
      }
      if (deprecatedLanguages[i + 1].equals(locale.getLanguage())) {
        aliases.add(factory.fromComponents(deprecatedLanguages[i],
            locale.getScript(), locale.getRegion(), locale.getVariant()));
        break;
      }
    }
  }

  private static void addImmediateParentRegions(GwtLocaleFactory factory,
      GwtLocale locale, Collection<GwtLocale> work) {
    String language = locale.getLanguage();
    String script = locale.getScript();
    String region = locale.getRegion();
    String variant = locale.getVariant();
    if (variant != null) {
      work.add(factory.fromComponents(language, script, region, null));
    }
    Set<String> immediateParents = RegionInheritance.getImmediateParents(region);
    for (String parent : immediateParents) {
      work.add(factory.fromComponents(language, script, parent, variant));
      if (variant != null) {
        work.add(factory.fromComponents(language, script, parent, null));
      }
    }
    if (immediateParents.isEmpty()) {
      work.add(factory.fromComponents(language, script, null, variant));
      if (variant != null) {
        work.add(factory.fromComponents(language, script, null, null));
      }
    }
    if (script != null) {
      work.add(factory.fromComponents(language, null, region, variant));
      if (variant != null) {
        work.add(factory.fromComponents(language, null, region, null));
      }
    }
  }

  /**
   * Add inherited regions for a given locale.
   * 
   * @param factory
   * @param inherits
   * @param language
   * @param script
   * @param region
   * @param variant
   */
  private static void addParentRegionLocales(GwtLocaleFactory factory,
      List<GwtLocale> inherits, String language, String script, String region,
      String variant) {
    for (String parent : RegionInheritance.getAllAncestors(region)) {
      inherits.add(factory.fromComponents(language, script, parent, variant));
    }
  }

  /**
   * Add special aliases for a given locale.
   * 
   * This includes things like choosing the default script/region for Chinese
   * based on the other one, handling Norwegian language changes, and treating
   * pt_BR as the default pt type.
   * 
   * @param factory GwtLocaleFactory to create new instances with
   * @param locale locale to add deprecated pair for
   * @param aliases where to store the alias if present
   */
  private static void addSpecialAliases(GwtLocaleFactory factory,
      GwtLocale locale, List<GwtLocale> aliases) {
    String language = locale.getLanguage();
    String script = locale.getScript();
    String region = locale.getRegion();
    String variant = locale.getVariant();
    if ("zh".equals(language)) {
      if (script == null) {
        // infer script from region
        if ("TW".equals(region)) {
          aliases.add(factory.fromComponents("zh", "Hant", region, variant));
        } else if ("CN".equals(region)) {
          aliases.add(factory.fromComponents("zh", "Hans", region, variant));
        }
      } else {
        if (region == null) {
          // Add aliases for main users of particular scripts
          aliases.add(factory.fromComponents("zh", script,
              "Hant".equals(script) ? "TW" : "CN", variant));
        }
      }
    } else if ("no".equals(language)) {
      if (variant == null || "BOKMAL".equals(variant)) {
        aliases.add(factory.fromComponents("nb", script, region, null));
        aliases.add(factory.fromComponents("no-bok", script, region, null));
      } else if ("NYNORSK".equals(variant)) {
        aliases.add(factory.fromComponents("nn", script, region, null));
        aliases.add(factory.fromComponents("no-nyn", script, region, null));
      }
    } else if ("nb".equals(language)) {
      aliases.add(factory.fromComponents("no", script, region, "BOKMAL"));
    } else if ("nn".equals(language)) {
      aliases.add(factory.fromComponents("no", script, region, "NYNORSK"));
    } else if ("pt".equals(language)) {
      if (region == null) {
        aliases.add(factory.fromComponents("pt", script, "BR", variant));
      } else if ("BR".equals(region)) {
        aliases.add(factory.fromComponents("pt", script, null, variant));
      }
    }
  }

  private static boolean equalsNullCheck(String str1, String str2) {
    if (str1 == null) {
      return str2 == null;
    }
    return str1.equals(str2);
  }

  /**
   * Compare strings, accounting for nulls (which are treated as before any
   * other value).
   * 
   * @param a first string
   * @param b second string
   * 
   * @return positive if a>b, negative if a<b, 0 if equal
   */
  private static int stringCompare(String a, String b) {
    if (a == null) {
      return b == null ? 0 : -1;
    }
    if (b == null) {
      return 1;
    }
    return a.compareTo(b);
  }

  private final GwtLocaleFactory factory;

  private final String language;

  private final String region;

  private final String script;

  private final String variant;

  private final Object cacheLock = new Object[0];
  
  // protected by cacheLock
  private List<GwtLocale> cachedSearchList;

  // protected by cacheLock
  private List<GwtLocale> cachedAliases;

  /**
   * Must only be called from a factory to preserve instance caching.
   */
  GwtLocaleImpl(GwtLocaleFactory factory, String language, String region,
      String script, String variant) {
    this.factory = factory;
    this.language = language;
    this.region = region;
    this.script = script;
    this.variant = variant;
  }

  public int compareTo(GwtLocale o) {
    int c = stringCompare(language, o.getLanguage());
    if (c == 0) {
      c = stringCompare(script, o.getScript());
    }
    if (c == 0) {
      c = stringCompare(region, o.getRegion());
    }
    if (c == 0) {
      c = stringCompare(variant, o.getVariant());
    }
    return c;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof GwtLocale)) {
      return false;
    }
    GwtLocale other = (GwtLocale) obj;
    return equalsNullCheck(language, other.getLanguage())
        && equalsNullCheck(region, other.getRegion())
        && equalsNullCheck(script, other.getScript())
        && equalsNullCheck(variant, other.getVariant());
  }

  public List<GwtLocale> getAliases() {
    // TODO(jat): more locale aliases? better way to encode them?
    synchronized (cacheLock) {
      if (cachedAliases == null) {
        cachedAliases = new ArrayList<GwtLocale>();
        GwtLocale canonicalForm = getCanonicalForm();
        Set<GwtLocale> seen = new HashSet<GwtLocale>();
        cachedAliases.add(canonicalForm);
        ArrayList<GwtLocale> nextGroup = new ArrayList<GwtLocale>();
        nextGroup.add(this);
        // Account for default script
        String defaultScript = DefaultLanguageScripts.getDefaultScript(language);
        if (defaultScript != null) {
          if (script == null) {
            nextGroup.add(factory.fromComponents(language, defaultScript,
                region, variant));
          } else if (script.equals(defaultScript)) {
            nextGroup.add(factory.fromComponents(language, null, region,
                variant));
          }
        }
        while (!nextGroup.isEmpty()) {
          List<GwtLocale> thisGroup = nextGroup;
          nextGroup = new ArrayList<GwtLocale>();
          for (GwtLocale locale : thisGroup) {
            if (seen.contains(locale)) {
              continue;
            }
            seen.add(locale);
            if (!locale.equals(canonicalForm)) {
              cachedAliases.add(locale);
            }
            addDeprecatedPairs(factory, locale, nextGroup);
            addSpecialAliases(factory, locale, nextGroup);
          }
        }
        cachedAliases = Collections.unmodifiableList(cachedAliases);
      }
      return cachedAliases;    
    }
  }

  public String getAsString() {
    StringBuilder buf = new StringBuilder();
    if (language != null) {
      buf.append(language);
    }
    if (script != null) {
      buf.append('_');
      buf.append(script);
    }
    if (region != null) {
      buf.append('_');
      buf.append(region);
    }
    if (variant != null) {
      buf.append('_');
      buf.append(variant);
    }
    return buf.toString();
  }

  /**
   * Returns this locale in canonical form.  Changes for canonical form are:
   * <ul>
   *  <li>Deprecated language/region tags are replaced with official versions
   * </ul>
   * 
   * @return GwtLocale instance 
   */
  public GwtLocale getCanonicalForm() {
    String canonLanguage = language;
    String canonScript = script;
    String canonRegion = region;
    String canonVariant = variant;
    // Handle deprecated language codes
    int n = deprecatedLanguages.length;
    for (int i = 0; i < n; i += 2) {
      if (deprecatedLanguages[i + 1].equals(canonLanguage)) {
        canonLanguage = deprecatedLanguages[i];
        break;
      }
    }
    // Handle deprecated region codes
    n = deprecatedRegions.length;
    for (int i = 0; i < n; i += 2) {
      if (deprecatedRegions[i + 1].equals(canonRegion)) {
        canonRegion = deprecatedRegions[i];
        break;
      }
    }
    // Special-case Chinese default scripts
    if ("zh".equals(canonLanguage)) {
      if (canonRegion != null) {
        if ("CN".equals(canonRegion) && "Hans".equals(canonScript)) {
          canonScript = null;
        } else if ("TW".equals(canonRegion) && "Hant".equals(canonScript)) {
          canonScript = null;
        }
      } else if ("Hans".equals(canonScript)) {
        canonRegion = "CN";
        canonScript = null;
      } else if ("Hant".equals(canonScript)) {
        canonRegion = "TW";
        canonScript = null;
      }
    }
    // Special-case no->nb/nn split
    if ("no-bok".equals(canonLanguage)) {
      canonLanguage = "nb";
      canonVariant = null;
    } else if ("no-nyn".equals(canonLanguage)) {
      canonLanguage = "nn";
      canonVariant = null;
    } else if ("no".equals(canonLanguage)) {
      if (canonVariant == null || "BOKMAL".equals(canonVariant)) {
        canonLanguage = "nb";
        canonVariant = null;
      } else if ("NYNORSK".equals(canonVariant)) {
        canonLanguage = "nn";
        canonVariant = null;
      }
    }
    // Remove any default script for the language
    if (canonScript != null && canonScript.equals(
        DefaultLanguageScripts.getDefaultScript(canonLanguage))) {
      canonScript = null;
    }
    return factory.fromComponents(canonLanguage, canonScript, canonRegion,
        canonVariant);
  }

  public List<GwtLocale> getCompleteSearchList() {
    // TODO(jat): get zh_Hant to come before zh in search list for zh_TW
    synchronized (cacheLock) {
      if (cachedSearchList == null) {
        cachedSearchList = new ArrayList<GwtLocale>();
        Set<GwtLocale> seen = new HashSet<GwtLocale>();
        List<GwtLocale> thisGroup = new ArrayList<GwtLocale>(this.getAliases());
        seen.addAll(thisGroup);
        GwtLocale defLocale = factory.getDefault();
        seen.add(defLocale);
        while (!thisGroup.isEmpty()) {
          cachedSearchList.addAll(thisGroup);
          List<GwtLocale> nextGroup = new ArrayList<GwtLocale>();
          for (GwtLocale locale : thisGroup) {
            List<GwtLocale> work = new ArrayList<GwtLocale>(locale.getAliases());
            work.removeAll(seen);
            nextGroup.addAll(work);
            seen.addAll(work);
            work.clear();
            if (locale.getRegion() != null) {
              addImmediateParentRegions(factory, locale, work);
            } else if (locale.getVariant() != null) {
              work.add(factory.fromComponents(locale.getLanguage(),
                  locale.getScript(), null, null));
            } else if (locale.getScript() != null) {
              work.add(factory.fromComponents(locale.getLanguage(), null, null,
                  null));
            }
            work.removeAll(seen);
            nextGroup.addAll(work);
            seen.addAll(work);
          }
          thisGroup = nextGroup;
        }
        if (!isDefault()) {
          cachedSearchList.add(defLocale);
        }
        cachedSearchList = Collections.unmodifiableList(cachedSearchList);
      }
      return cachedSearchList;
    }
  }

  /**
   * Return a list of locales to search for, in order of preference.  The
   * current locale is always first on the list.  Aliases are not included
   * in the list -- use {@link #getAliases} to expand those.
   * 
   * @return inheritance list
   */
  public List<GwtLocale> getInheritanceChain() {
    List<GwtLocale> inherits = new ArrayList<GwtLocale>();
    inherits.add(this);
    if (variant != null) {
      inherits.add(factory.fromComponents(language, script, region, null));
    }
    if (region != null) {
      addParentRegionLocales(factory, inherits, language, script, region,
          null);
      inherits.add(factory.fromComponents(language, script, null, null));
    }
    if (script != null) {
      inherits.add(factory.fromComponents(language, null, region, null));
      addParentRegionLocales(factory, inherits, language, null, region, null);
      if (region != null) {
        inherits.add(factory.fromComponents(language, null, null, null));
      }
    }
    if (language != null) {
      inherits.add(factory.fromComponents(null, null, null, null));
    }
    return inherits;
  }

  public String getLanguage() {
    return language;
  }

  public String getLanguageNotNull() {
    return language == null ? "" : language;
  }

  public String getRegion() {
    return region;
  }

  public String getRegionNotNull() {
    return region == null ? "" : region;
  }

  public String getScript() {
    return script;
  }

  public String getScriptNotNull() {
    return script == null ? "" : script;
  }

  public String getVariant() {
    return variant;
  }

  public String getVariantNotNull() {
    return variant == null ? "" : variant;
  }

  @Override
  public int hashCode() {
    int result = ((language == null) ? 0 : language.hashCode());
    result = 37 * result + ((region == null) ? 0 : region.hashCode());
    result = 43 * result + ((script == null) ? 0 : script.hashCode());
    result = 53 * result + ((variant == null) ? 0 : variant.hashCode());
    return result;
  }

  /**
   * Return true if this locale inherits from the specified locale.  Note that
   * locale.inheritsFrom(locale) is false -- if you want that to be true, you
   * should just use locale.getInheritanceChain().contains(x).
   * 
   * @param parent locale to test against
   * @return true if parent is an ancestor of this locale
   */
  public boolean inheritsFrom(GwtLocale parent) {
    if (equals(parent)) {
      return false;
    }
    return getInheritanceChain().contains(parent);
  }

  public boolean isDefault() {
    return language == null;
  }

  @Override
  public String toString() {
    if (language == null) {
      return DEFAULT_LOCALE;
    }
    return getAsString();
  }

  /**
   * Checks if this locale uses the same script as another locale, taking into
   * account default scripts.
   * 
   * @param other
   * @return true if the scripts are the same
   */
  public boolean usesSameScript(GwtLocale other) {
    // The number of aliases is very small, so n^2 isn't a problem here.
    List<GwtLocale> myAliases = getAliases();
    List<GwtLocale> otherAliases = other.getAliases();
    for (GwtLocale alias : myAliases) {
      for (GwtLocale otherAlias : otherAliases) {
        if (equalsNullCheck(alias.getScript(), otherAlias.getScript())) {
          return true;
        }
      }
    }
    return false;
  }
}
