/*
 * 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.miscellaneous;

import java.io.Reader;
import java.io.StringReader;
import org.apache.lucene.analysis.BaseTokenStreamFactoryTestCase;
import org.apache.lucene.analysis.TokenStream;

public class TestCapitalizationFilterFactory extends BaseTokenStreamFactoryTestCase {

  public void testCapitalization() throws Exception {
    Reader reader = new StringReader("kiTTEN");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory("Capitalization", "keep", "and the it BIG", "onlyFirstWord", "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"Kitten"});
  }

  public void testCapitalization2() throws Exception {
    Reader reader = new StringReader("and");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"And"});
  }

  /** first is forced, but it's not a keep word, either */
  public void testCapitalization3() throws Exception {
    Reader reader = new StringReader("AnD");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"And"});
  }

  public void testCapitalization4() throws Exception {
    Reader reader = new StringReader("AnD");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "false")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"And"});
  }

  public void testCapitalization5() throws Exception {
    Reader reader = new StringReader("big");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"Big"});
  }

  public void testCapitalization6() throws Exception {
    Reader reader = new StringReader("BIG");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"BIG"});
  }

  public void testCapitalization7() throws Exception {
    Reader reader = new StringReader("Hello thEre my Name is Ryan");
    TokenStream stream = keywordMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"Hello there my name is ryan"});
  }

  public void testCapitalization8() throws Exception {
    Reader reader = new StringReader("Hello thEre my Name is Ryan");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "false",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"Hello", "There", "My", "Name", "Is", "Ryan"});
  }

  public void testCapitalization9() throws Exception {
    Reader reader = new StringReader("Hello thEre my Name is Ryan");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "false",
                "minWordLength",
                "3",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"Hello", "There", "my", "Name", "is", "Ryan"});
  }

  public void testCapitalization10() throws Exception {
    Reader reader = new StringReader("McKinley");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "false",
                "minWordLength",
                "3",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"Mckinley"});
  }

  /** using "McK" as okPrefix */
  public void testCapitalization11() throws Exception {
    Reader reader = new StringReader("McKinley");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "false",
                "minWordLength",
                "3",
                "okPrefix",
                "McK",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"McKinley"});
  }

  /** test with numbers */
  public void testCapitalization12() throws Exception {
    Reader reader = new StringReader("1st 2nd third");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "false",
                "minWordLength",
                "3",
                "okPrefix",
                "McK",
                "forceFirstLetter",
                "false")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"1st", "2nd", "Third"});
  }

  public void testCapitalization13() throws Exception {
    Reader reader = new StringReader("the The the");
    TokenStream stream = keywordMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "and the it BIG",
                "onlyFirstWord",
                "false",
                "minWordLength",
                "3",
                "okPrefix",
                "McK",
                "forceFirstLetter",
                "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"The The the"});
  }

  public void testKeepIgnoreCase() throws Exception {
    Reader reader = new StringReader("kiTTEN");
    TokenStream stream = keywordMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "kitten",
                "keepIgnoreCase",
                "true",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "true")
            .create(stream);

    assertTokenStreamContents(stream, new String[] {"KiTTEN"});
  }

  public void testKeepIgnoreCase2() throws Exception {
    Reader reader = new StringReader("kiTTEN");
    TokenStream stream = keywordMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keep",
                "kitten",
                "keepIgnoreCase",
                "true",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "false")
            .create(stream);

    assertTokenStreamContents(stream, new String[] {"kiTTEN"});
  }

  public void testKeepIgnoreCase3() throws Exception {
    Reader reader = new StringReader("kiTTEN");
    TokenStream stream = keywordMockTokenizer(reader);
    stream =
        tokenFilterFactory(
                "Capitalization",
                "keepIgnoreCase",
                "true",
                "onlyFirstWord",
                "true",
                "forceFirstLetter",
                "false")
            .create(stream);

    assertTokenStreamContents(stream, new String[] {"Kitten"});
  }

  /**
   * Test CapitalizationFilterFactory's minWordLength option.
   *
   * <p>This is very weird when combined with ONLY_FIRST_WORD!!!
   */
  public void testMinWordLength() throws Exception {
    Reader reader = new StringReader("helo testing");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory("Capitalization", "onlyFirstWord", "true", "minWordLength", "5")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"helo", "Testing"});
  }

  /**
   * Test CapitalizationFilterFactory's maxWordCount option with only words of 1 in each token (it
   * should do nothing)
   */
  public void testMaxWordCount() throws Exception {
    Reader reader = new StringReader("one two three four");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream = tokenFilterFactory("Capitalization", "maxWordCount", "2").create(stream);
    assertTokenStreamContents(stream, new String[] {"One", "Two", "Three", "Four"});
  }

  /** Test CapitalizationFilterFactory's maxWordCount option when exceeded */
  public void testMaxWordCount2() throws Exception {
    Reader reader = new StringReader("one two three four");
    TokenStream stream = keywordMockTokenizer(reader);
    stream = tokenFilterFactory("Capitalization", "maxWordCount", "2").create(stream);
    assertTokenStreamContents(stream, new String[] {"one two three four"});
  }

  /**
   * Test CapitalizationFilterFactory's maxTokenLength option when exceeded
   *
   * <p>This is weird, it is not really a max, but inclusive (look at 'is')
   */
  public void testMaxTokenLength() throws Exception {
    Reader reader = new StringReader("this is a test");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream = tokenFilterFactory("Capitalization", "maxTokenLength", "2").create(stream);
    assertTokenStreamContents(stream, new String[] {"this", "is", "A", "test"});
  }

  /** Test CapitalizationFilterFactory's forceFirstLetter option */
  public void testForceFirstLetterWithKeep() throws Exception {
    Reader reader = new StringReader("kitten");
    TokenStream stream = whitespaceMockTokenizer(reader);
    stream =
        tokenFilterFactory("Capitalization", "keep", "kitten", "forceFirstLetter", "true")
            .create(stream);
    assertTokenStreamContents(stream, new String[] {"Kitten"});
  }

  /** Test that bogus arguments result in exception */
  public void testBogusArguments() throws Exception {
    IllegalArgumentException expected =
        expectThrows(
            IllegalArgumentException.class,
            () -> {
              tokenFilterFactory("Capitalization", "bogusArg", "bogusValue");
            });
    assertTrue(expected.getMessage().contains("Unknown parameters"));
  }

  /** Test that invalid arguments result in exception */
  public void testInvalidArguments() throws Exception {
    for (final String arg : new String[] {"minWordLength", "maxTokenLength", "maxWordCount"}) {
      IllegalArgumentException expected =
          expectThrows(
              IllegalArgumentException.class,
              () -> {
                Reader reader = new StringReader("foo foobar super-duper-trooper");
                TokenStream stream = whitespaceMockTokenizer(reader);

                tokenFilterFactory(
                        "Capitalization",
                        "keep",
                        "and the it BIG",
                        "onlyFirstWord",
                        "false",
                        arg,
                        "-3",
                        "okPrefix",
                        "McK",
                        "forceFirstLetter",
                        "true")
                    .create(stream);
              });
      assertTrue(
          expected.getMessage().contains(arg + " must be greater than or equal to zero")
              || expected.getMessage().contains(arg + " must be greater than zero"));
    }
  }
}
