using System;
using System.IO;
using Console = Lucene.Net.Util.SystemConsole;

namespace Lucene.Net.QueryParsers.Classic
{
    /*
     * 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>
    /// An efficient implementation of JavaCC's <see cref="ICharStream"/> interface.  
    /// <para/>
    /// Note that
    /// this does not do line-number counting, but instead keeps track of the
    /// character position of the token in the input, as required by Lucene's <see cref="Lucene.Net.Analysis.Token" />
    /// API.
    /// </summary>
    public sealed class FastCharStream : ICharStream
    {
        internal char[] buffer = null;
        
        internal int bufferLength = 0; // end of valid chars
        internal int bufferPosition = 0; // next char to read
        
        internal int tokenStart = 0; // offset in buffer
        internal int bufferStart = 0; // position in file of buffer
        
        internal TextReader input; // source of chars

        /// <summary>
        /// Constructs from a <see cref="TextReader"/>. 
        /// </summary>
        public FastCharStream(TextReader r)
        {
            input = r;
        }
        
        public char ReadChar()
        {
            if (bufferPosition >= bufferLength)
                Refill();
            return buffer[bufferPosition++];
        }
        
        private void  Refill()
        {
            int newPosition = bufferLength - tokenStart;
            
            if (tokenStart == 0)
            {
                // token won't fit in buffer
                if (buffer == null)
                {
                    // first time: alloc buffer
                    buffer = new char[2048];
                }
                else if (bufferLength == buffer.Length)
                {
                    // grow buffer
                    char[] newBuffer = new char[buffer.Length * 2];
                    Array.Copy(buffer, 0, newBuffer, 0, bufferLength);
                    buffer = newBuffer;
                }
            }
            else
            {
                // shift token to front
                Array.Copy(buffer, tokenStart, buffer, 0, newPosition);
            }
            
            bufferLength = newPosition; // update state
            bufferPosition = newPosition;
            bufferStart += tokenStart;
            tokenStart = 0;
            
            int charsRead = input.Read(buffer, newPosition, buffer.Length - newPosition);
            if (charsRead <= 0)
                throw new IOException("read past eof");
            else
                bufferLength += charsRead;
        }
        
        public char BeginToken()
        {
            tokenStart = bufferPosition;
            return ReadChar();
        }
        
        public void  BackUp(int amount)
        {
            bufferPosition -= amount;
        }

        public string Image => new string(buffer, tokenStart, bufferPosition - tokenStart);

        public char[] GetSuffix(int len)
        {
            char[] value = new char[len];
            Array.Copy(buffer, bufferPosition - len, value, 0, len);
            return value;
        }
        
        public void Done()
        {
            try
            {
                input.Dispose();
            }
            catch (IOException e)
            {
                Console.Error.WriteLine("Caught: " + e + "; ignoring.");
            }
        }

        public int Column => bufferStart + bufferPosition;

        public int Line => 1;

        public int EndColumn => bufferStart + bufferPosition;

        public int EndLine => 1;

        public int BeginColumn => bufferStart + tokenStart;

        public int BeginLine => 1;
    }
}