// Path: src/main/java/com/worksap/nlp/sudachi/dictionary/Grammar.java
// public interface Grammar {
// 
//     /**
//      * Returns the number of types of part-of-speech.
//      *
//      * The IDs of part-of-speech are within the range of 0 to
//      * {@code getPartOfSpeechSize() - 1}.
//      *
//      * @return the number of types of part-of-speech
//      */
//     public int getPartOfSpeechSize();
// 
//     /**
//      * Returns the array of strings of part-of-speech name.
//      *
//      * The name is divided into layers.
//      *
//      * @param posId
//      *            the ID of the part-of-speech
//      * @return the list of strings of part-of-speech name
//      * @throws IndexOutOfBoundsException
//      *             if {@code posId} is out of the range
//      */
//     public POS getPartOfSpeechString(short posId);
// 
//     /**
//      * Returns the the ID corresponding to the part-of-speech name.
//      *
//      * <p>
//      * If there is not such the part-of-speech name, -1 is returned.
//      *
//      * @param pos
//      *            the list of string of part-of-speech name
//      * @return the ID corresponding to the part-of-speech name, or -1 without
//      *         corresponding one.
//      */
//     public short getPartOfSpeechId(List<String> pos);
// 
//     /**
//      * Returns the cost of the specified connection.
//      *
//      * <p>
//      * When the Id is out of the range, the behavior is undefined.
//      *
//      * @param left
//      *            the right-ID of the left node
//      * @param right
//      *            the left-ID of the right node
//      * @return the cost of the connection
//      */
//     public short getConnectCost(short left, short right);
// 
//     /**
//      * Set the connection costs.
//      *
//      * <p>
//      * When the Id is out of the range, the behavior is undefined.
//      *
//      * @param left
//      *            the right-ID of the left node
//      * @param right
//      *            the left-ID of the right node
//      * @param cost
//      *            the cost of the connection
//      */
//     public void setConnectCost(short left, short right, short cost);
// 
//     /**
//      * Returns the parameter of the beginning of sentence.
//      *
//      * <p>
//      * The following are the parameters.
//      * 
//      * <pre>
//      * {@code { left-ID, rightID, cost } }
//      * </pre>
//      *
//      * @return the parameter of the beginning of sentence
//      */
//     public short[] getBOSParameter();
// 
//     /**
//      * Returns the parameter of the end of sentence.
//      *
//      * <p>
//      * The following are the parameters.
//      * 
//      * <pre>
//      * {@code { left-ID, rightID, cost } }
//      * </pre>
//      *
//      * @return the parameter of the end of sentence
//      */
//     public short[] getEOSParameter();
// 
//     public CharacterCategory getCharacterCategory();
// 
//     public void setCharacterCategory(CharacterCategory charCategory);
// 
//     /** the cost of inhibited connections */
//     public static final short INHIBITED_CONNECTION = Short.MAX_VALUE;
// 
//     default Connection getConnection() {
//         throw new UnsupportedOperationException();
//     }
// }


import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.nio.charset.StandardCharsets;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import com.worksap.nlp.sudachi.dictionary.Grammar;
/*
 * Copyright (c) 2017-2022 Works Applications Co., Ltd.
 *
 * 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.worksap.nlp.sudachi;



/**
 * A plugin that rewrites the characters of input texts.
 *
 * <p>
 * This plugin rewites the characters by the user-defined rules, converts them
 * to lower case by {@link Character#toLowerCase} and normalized by
 * {@link java.text.Normalizer#normalize} with {@code NFKC}.
 *
 * <p>
 * {@link Dictionary} initialize this plugin with {@link Settings}. It can be
 * refered as {@link Plugin#settings}.
 *
 * <p>
 * The following is an example of settings.
 *
 * <pre>
 * {@code
 *   {
 *     "class" : "com.worksap.nlp.sudachi.DefaultInputTextPlugin",
 *     "rewriteDef" : "rewrite.def"
 *   }
 * }
 * </pre>
 *
 * {@code rewriteDef} is the file path of the rules of character rewriting. If
 * {@code rewirteDef} is not defined, this plugin uses the default rules.
 *
 * <p>
 * The following is an example of rewriting rules.
 *
 * <pre>
 * {@code
 * # single code point: this character is skipped in character normalization
 * 髙
 * # rewrite rule: <target> <replacement>
 * A' Ā
 * }
 * </pre>
 */
class DefaultInputTextPlugin extends InputTextPlugin {

    /** the file path of the rules */
    Config.Resource<InputStream> rewriteDef;

    private Set<Integer> ignoreNormalizeSet = new HashSet<>();
    private Map<Character, Integer> keyLengths = new HashMap<>();
    private Map<String, String> replaceCharMap = new HashMap<>();

    /**
     * Reads the rewriting rules from the specified file.
     *
     * @throws IOException
     *             if the file is not available.
     */
    @Override
// Path: src/main/java/com/worksap/nlp/sudachi/dictionary/Grammar.java
// public interface Grammar {
// 
//     /**
//      * Returns the number of types of part-of-speech.
//      *
//      * The IDs of part-of-speech are within the range of 0 to
//      * {@code getPartOfSpeechSize() - 1}.
//      *
//      * @return the number of types of part-of-speech
//      */
//     public int getPartOfSpeechSize();
// 
//     /**
//      * Returns the array of strings of part-of-speech name.
//      *
//      * The name is divided into layers.
//      *
//      * @param posId
//      *            the ID of the part-of-speech
//      * @return the list of strings of part-of-speech name
//      * @throws IndexOutOfBoundsException
//      *             if {@code posId} is out of the range
//      */
//     public POS getPartOfSpeechString(short posId);
// 
//     /**
//      * Returns the the ID corresponding to the part-of-speech name.
//      *
//      * <p>
//      * If there is not such the part-of-speech name, -1 is returned.
//      *
//      * @param pos
//      *            the list of string of part-of-speech name
//      * @return the ID corresponding to the part-of-speech name, or -1 without
//      *         corresponding one.
//      */
//     public short getPartOfSpeechId(List<String> pos);
// 
//     /**
//      * Returns the cost of the specified connection.
//      *
//      * <p>
//      * When the Id is out of the range, the behavior is undefined.
//      *
//      * @param left
//      *            the right-ID of the left node
//      * @param right
//      *            the left-ID of the right node
//      * @return the cost of the connection
//      */
//     public short getConnectCost(short left, short right);
// 
//     /**
//      * Set the connection costs.
//      *
//      * <p>
//      * When the Id is out of the range, the behavior is undefined.
//      *
//      * @param left
//      *            the right-ID of the left node
//      * @param right
//      *            the left-ID of the right node
//      * @param cost
//      *            the cost of the connection
//      */
//     public void setConnectCost(short left, short right, short cost);
// 
//     /**
//      * Returns the parameter of the beginning of sentence.
//      *
//      * <p>
//      * The following are the parameters.
//      * 
//      * <pre>
//      * {@code { left-ID, rightID, cost } }
//      * </pre>
//      *
//      * @return the parameter of the beginning of sentence
//      */
//     public short[] getBOSParameter();
// 
//     /**
//      * Returns the parameter of the end of sentence.
//      *
//      * <p>
//      * The following are the parameters.
//      * 
//      * <pre>
//      * {@code { left-ID, rightID, cost } }
//      * </pre>
//      *
//      * @return the parameter of the end of sentence
//      */
//     public short[] getEOSParameter();
// 
//     public CharacterCategory getCharacterCategory();
// 
//     public void setCharacterCategory(CharacterCategory charCategory);
// 
//     /** the cost of inhibited connections */
//     public static final short INHIBITED_CONNECTION = Short.MAX_VALUE;
// 
//     default Connection getConnection() {
//         throw new UnsupportedOperationException();
//     }
// }


// Path: src/main/java/com/worksap/nlp/sudachi/DefaultInputTextPlugin.java
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.nio.charset.StandardCharsets;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import com.worksap.nlp.sudachi.dictionary.Grammar;

/*
 * Copyright (c) 2017-2022 Works Applications Co., Ltd.
 *
 * 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.worksap.nlp.sudachi;



/**
 * A plugin that rewrites the characters of input texts.
 *
 * <p>
 * This plugin rewites the characters by the user-defined rules, converts them
 * to lower case by {@link Character#toLowerCase} and normalized by
 * {@link java.text.Normalizer#normalize} with {@code NFKC}.
 *
 * <p>
 * {@link Dictionary} initialize this plugin with {@link Settings}. It can be
 * refered as {@link Plugin#settings}.
 *
 * <p>
 * The following is an example of settings.
 *
 * <pre>
 * {@code
 *   {
 *     "class" : "com.worksap.nlp.sudachi.DefaultInputTextPlugin",
 *     "rewriteDef" : "rewrite.def"
 *   }
 * }
 * </pre>
 *
 * {@code rewriteDef} is the file path of the rules of character rewriting. If
 * {@code rewirteDef} is not defined, this plugin uses the default rules.
 *
 * <p>
 * The following is an example of rewriting rules.
 *
 * <pre>
 * {@code
 * # single code point: this character is skipped in character normalization
 * 髙
 * # rewrite rule: <target> <replacement>
 * A' Ā
 * }
 * </pre>
 */
class DefaultInputTextPlugin extends InputTextPlugin {

    /** the file path of the rules */
    Config.Resource<InputStream> rewriteDef;

    private Set<Integer> ignoreNormalizeSet = new HashSet<>();
    private Map<Character, Integer> keyLengths = new HashMap<>();
    private Map<String, String> replaceCharMap = new HashMap<>();

    /**
     * Reads the rewriting rules from the specified file.
     *
     * @throws IOException
     *             if the file is not available.
     */
    @Override
    public void setUp(Grammar grammar) throws IOException {