﻿using Lucene.Net.Analysis.Tokenattributes;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace Lucene.Net.Analysis.Pattern
{
    /*
     * 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>
    /// This tokenizer uses regex pattern matching to construct distinct tokens
    /// for the input stream.  It takes two arguments:  "pattern" and "group".
    /// <p/>
    /// <ul>
    /// <li>"pattern" is the regular expression.</li>
    /// <li>"group" says which group to extract into tokens.</li>
    ///  </ul>
    /// <para>
    /// group=-1 (the default) is equivalent to "split".  In this case, the tokens will
    /// be equivalent to the output from (without empty tokens):
    /// <seealso cref="String#split(java.lang.String)"/>
    /// </para>
    /// <para>
    /// Using group >= 0 selects the matching group as the token.  For example, if you have:<br/>
    /// <pre>
    ///  pattern = \'([^\']+)\'
    ///  group = 0
    ///  input = aaa 'bbb' 'ccc'
    /// </pre>
    /// the output will be two tokens: 'bbb' and 'ccc' (including the ' marks).  With the same input
    /// but using group=1, the output would be: bbb and ccc (no ' marks)
    /// </para>
    /// <para>NOTE: This Tokenizer does not output tokens that are of zero length.</para>
    /// </summary>
    /// <seealso cref= Pattern </seealso>
    public sealed class PatternTokenizer : Tokenizer
    {

        private readonly ICharTermAttribute termAtt;
        private readonly IOffsetAttribute offsetAtt;

        private readonly StringBuilder str = new StringBuilder();
        private int index;
        private bool isReset = false;

        private readonly int group;
        private Match matcher;
        private readonly Regex pattern;

        /// <summary>
        /// creates a new PatternTokenizer returning tokens from group (-1 for split functionality) </summary>
        public PatternTokenizer(TextReader input, Regex pattern, int group)
              : this(AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY, input, pattern, group)
        {
        }

        /// <summary>
        /// creates a new PatternTokenizer returning tokens from group (-1 for split functionality) </summary>
        public PatternTokenizer(AttributeFactory factory, TextReader input, Regex pattern, int group)
              : base(factory, input)
        {
            this.termAtt = AddAttribute<ICharTermAttribute>();
            this.offsetAtt = AddAttribute<IOffsetAttribute>();
            this.group = group;

            // Use "" instead of str so don't consume chars
            // (fillBuffer) from the input on throwing IAE below:
            this.matcher = pattern.Match("");
            this.pattern = pattern;

            // confusingly group count depends ENTIRELY on the pattern but is only accessible via matcher
            var groupCount = pattern.GetGroupNumbers().Length;
            if (group >= 0 && group > groupCount)
            {
                throw new System.ArgumentException("invalid group specified: pattern only has: " + groupCount + " capturing groups");
            }

        }

        public override bool IncrementToken()
        {
            if (index >= str.Length)
            {
                return false;
            }
            ClearAttributes();

            if (group >= 0)
            {

                // match a specific group
                if (matcher.Success)
                {
                    do
                    {
                        // We have alredy parsed from this index, go to the next token.
                        if (!isReset && matcher.Groups[group].Index == index)
                        {
                            continue;
                        }
                        isReset = false;

                        index = matcher.Groups[group].Index;
                        int endIndex = matcher.Groups[group].Index + matcher.Groups[group].Length;

                        if (index == endIndex)
                        {
                            continue;
                        }

                        termAtt.SetEmpty().Append(str.ToString(), index, endIndex);
                        offsetAtt.SetOffset(CorrectOffset(index), CorrectOffset(endIndex));
                        return true;

                    } while ((matcher = matcher.NextMatch()).Success);
                }


                index = int.MaxValue; // mark exhausted
                return false;

            }
            else
            {

                // String.split() functionality
                if (matcher.Success)
                {
                    do
                    {
                        if (matcher.Index - index > 0)
                        {
                            // found a non-zero-length token
                            termAtt.SetEmpty().Append(str.ToString(), index, matcher.Index);
                            offsetAtt.SetOffset(CorrectOffset(index), CorrectOffset(matcher.Index));
                            index = matcher.Index + matcher.Length;
                            return true;
                        }

                        isReset = false;
                        index = matcher.Index + matcher.Length;
                    } while ((matcher = matcher.NextMatch()).Success);
                }

                if (str.Length - index == 0)
                {
                    index = int.MaxValue; // mark exhausted
                    return false;
                }

                termAtt.SetEmpty().Append(str.ToString(), index, str.Length);
                offsetAtt.SetOffset(CorrectOffset(index), CorrectOffset(str.Length));
                index = int.MaxValue; // mark exhausted
                return true;
            }
        }

        public override void End()
        {
            base.End();
            int ofs = CorrectOffset(str.Length);
            offsetAtt.SetOffset(ofs, ofs);
        }

        public override void Reset()
        {
            base.Reset();
            FillBuffer(str, input);

            // LUCENENET: Since we need to "reset" the Match
            // object, we also need an "isReset" flag to indicate
            // whether we are at the head of the match and to 
            // take the appropriate measures to ensure we don't 
            // overwrite our matcher variable with 
            // matcher = matcher.NextMatch();
            // before it is time. A string could potentially
            // match on index 0, so we need another variable to
            // manage this state.
            matcher = pattern.Match(str.ToString());
            isReset = true;
            index = 0;
        }

        // TODO: we should see if we can make this tokenizer work without reading
        // the entire document into RAM, perhaps with Matcher.hitEnd/requireEnd ?
        internal readonly char[] buffer = new char[8192];

        private void FillBuffer(StringBuilder sb, TextReader input)
        {
            int len;
            sb.Length = 0;
            while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                sb.Append(buffer, 0, len);
            }
        }
    }
}