// lucene version compatibility level: 4.8.1
using Lucene.Net.Analysis.Cn.Smart.Hhmm;
using Lucene.Net.Support;
using System.Collections.Generic;

namespace Lucene.Net.Analysis.Cn.Smart
{
    /*
     * 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.
     */

    /// <summary>
    /// Segment a sentence of Chinese text into words.
    /// <para/>
    /// @lucene.experimental
    /// </summary>
    internal class WordSegmenter
    {
        private HHMMSegmenter hhmmSegmenter = new HHMMSegmenter();

        private SegTokenFilter tokenFilter = new SegTokenFilter();

        /// <summary>
        /// Segment a sentence into words with <see cref="HHMMSegmenter"/>
        /// </summary>
        /// <param name="sentence">input sentence</param>
        /// <param name="startOffset"> start offset of sentence</param>
        /// <returns><see cref="IList{T}"/> of <see cref="SegToken"/>.</returns>
        public virtual IList<SegToken> SegmentSentence(string sentence, int startOffset)
        {

            IList<SegToken> segTokenList = hhmmSegmenter.Process(sentence);
            // tokens from sentence, excluding WordType.SENTENCE_BEGIN and WordType.SENTENCE_END
            IList<SegToken> result = Collections.EmptyList<SegToken>();

            if (segTokenList.Count > 2) // if its not an empty sentence
                result = segTokenList.SubList(1, segTokenList.Count - 1);

            foreach (SegToken st in result)
            {
                ConvertSegToken(st, sentence, startOffset);
            }

            return result;
        }

        /// <summary>
        /// Process a <see cref="SegToken"/> so that it is ready for indexing.
        /// </summary>
        /// <param name="st">st input <see cref="SegToken"/></param>
        /// <param name="sentence">associated Sentence</param>
        /// <param name="sentenceStartOffset">offset into sentence</param>
        /// <returns>Lucene <see cref="SegToken"/></returns>
        public virtual SegToken ConvertSegToken(SegToken st, string sentence,
            int sentenceStartOffset)
        {

            switch (st.WordType)
            {
                case WordType.STRING:
                case WordType.NUMBER:
                case WordType.FULLWIDTH_NUMBER:
                case WordType.FULLWIDTH_STRING:
                    st.CharArray = sentence.Substring(st.StartOffset, st.EndOffset - st.StartOffset)
                        .ToCharArray();
                    break;
                default:
                    break;
            }

            st = tokenFilter.Filter(st);
            st.StartOffset += sentenceStartOffset;
            st.EndOffset += sentenceStartOffset;
            return st;
        }
    }
}
