/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.lucene.analysis.cz;

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.CharArraySet;
import org.apache.lucene.analysis.LowerCaseFilter;
import org.apache.lucene.analysis.StopFilter;
import org.apache.lucene.analysis.StopwordAnalyzerBase;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.WordlistLoader;
import org.apache.lucene.analysis.miscellaneous.SetKeywordMarkerFilter;
import org.apache.lucene.analysis.standard.StandardTokenizer;
import org.apache.lucene.util.IOUtils;

/**
 * {@link Analyzer} for Czech language.
 *
 * <p>Supports an external list of stopwords (words that will not be indexed at all). A default set
 * of stopwords is used unless an alternative list is specified.
 *
 * @since 3.1
 */
public final class CzechAnalyzer extends StopwordAnalyzerBase {
  /** File containing default Czech stopwords. */
  public static final String DEFAULT_STOPWORD_FILE = "stopwords.txt";

  /**
   * Returns a set of default Czech-stopwords
   *
   * @return a set of default Czech-stopwords
   */
  public static final CharArraySet getDefaultStopSet() {
    return DefaultSetHolder.DEFAULT_SET;
  }

  private static class DefaultSetHolder {
    private static final CharArraySet DEFAULT_SET;

    static {
      try {
        DEFAULT_SET =
            WordlistLoader.getWordSet(
                IOUtils.getDecodingReader(
                    CzechAnalyzer.class, DEFAULT_STOPWORD_FILE, StandardCharsets.UTF_8),
                "#");
      } catch (IOException ex) {
        // default set should always be present as it is part of the
        // distribution (JAR)
        throw new RuntimeException("Unable to load default stopword set");
      }
    }
  }

  private final CharArraySet stemExclusionTable;

  /** Builds an analyzer with the default stop words ({@link #getDefaultStopSet()}). */
  public CzechAnalyzer() {
    this(DefaultSetHolder.DEFAULT_SET);
  }

  /**
   * Builds an analyzer with the given stop words.
   *
   * @param stopwords a stopword set
   */
  public CzechAnalyzer(CharArraySet stopwords) {
    this(stopwords, CharArraySet.EMPTY_SET);
  }

  /**
   * Builds an analyzer with the given stop words and a set of work to be excluded from the {@link
   * CzechStemFilter}.
   *
   * @param stopwords a stopword set
   * @param stemExclusionTable a stemming exclusion set
   */
  public CzechAnalyzer(CharArraySet stopwords, CharArraySet stemExclusionTable) {
    super(stopwords);
    this.stemExclusionTable = CharArraySet.unmodifiableSet(CharArraySet.copy(stemExclusionTable));
  }

  /**
   * Creates {@link org.apache.lucene.analysis.Analyzer.TokenStreamComponents} used to tokenize all
   * the text in the provided {@link Reader}.
   *
   * @return {@link org.apache.lucene.analysis.Analyzer.TokenStreamComponents} built from a {@link
   *     StandardTokenizer} filtered with {@link LowerCaseFilter}, {@link StopFilter}, and {@link
   *     CzechStemFilter} (only if version is &gt;= LUCENE_31). If a stem exclusion set is provided
   *     via {@link #CzechAnalyzer(CharArraySet, CharArraySet)} a {@link SetKeywordMarkerFilter} is
   *     added before {@link CzechStemFilter}.
   */
  @Override
  protected TokenStreamComponents createComponents(String fieldName) {
    final Tokenizer source = new StandardTokenizer();
    TokenStream result = new LowerCaseFilter(source);
    result = new StopFilter(result, stopwords);
    if (!this.stemExclusionTable.isEmpty())
      result = new SetKeywordMarkerFilter(result, stemExclusionTable);
    result = new CzechStemFilter(result);
    return new TokenStreamComponents(source, result);
  }

  @Override
  protected TokenStream normalize(String fieldName, TokenStream in) {
    return new LowerCaseFilter(in);
  }
}
