package morfologik.stemming.polish;

import java.io.IOException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Iterator;
import java.util.List;

import morfologik.stemming.Dictionary;
import morfologik.stemming.DictionaryLookup;
import morfologik.stemming.IStemmer;
import morfologik.stemming.WordData;

/**
 * A dictionary-based stemmer for the Polish language. Instances of this class
 * are not thread safe.
 * 
 * @see morfologik.stemming.DictionaryLookup
 */
public final class PolishStemmer implements IStemmer, Iterable<WordData> {
  /**
   * The underlying dictionary, loaded once (lazily).
   */
  private static Dictionary dictionary;

  /** Dictionary lookup delegate. */
  private final DictionaryLookup lookup;

  public PolishStemmer() {
    synchronized (getClass()) {
      if (dictionary == null) {
        try {
          dictionary = AccessController.doPrivileged(new PrivilegedExceptionAction<Dictionary>() {
            @Override
            public Dictionary run() throws Exception {
              URL dictResource = getClass().getResource("polish.dict");
              if (dictResource == null) {
                throw new IOException("Polish dictionary resource not found.");
              }
              return Dictionary.read(dictResource);
            }
          });
        } catch (PrivilegedActionException e) {
          throw new RuntimeException("Could not read dictionary data.", e.getException());
        }
      }
    }

    lookup = new DictionaryLookup(dictionary);
  }

  /**
   * @return Return the underlying {@link Dictionary} driving the stemmer.
   */
  public Dictionary getDictionary() {
    return dictionary;
  }

  /**
   * {@inheritDoc}
   */
  public List<WordData> lookup(CharSequence word) {
    return lookup.lookup(word);
  }

  /**
   * Iterates over all dictionary forms stored in this stemmer.
   */
  public Iterator<WordData> iterator() {
    return lookup.iterator();
  }
}
