﻿using J2N.Text;
using Lucene.Net.Support.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Lucene.Net.Facet.Taxonomy.WriterCache
{
    /*
     * 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>
    /// Similar to <see cref="StringBuilder"/>, but with a more efficient growing strategy.
    /// This class uses char array blocks to grow.
    /// <para/>
    /// @lucene.experimental
    /// </summary>
    // LUCENENET NOTE: The serialization features here are strictly for testing purposes,
    // therefore it doesn't make any difference what type of serialization is used. 
    // To make things simpler, we are using BinaryReader and BinaryWriter since 
    // BinaryFormatter is not implemented in .NET Standard 1.x.
    internal class CharBlockArray : ICharSequence
    {
        private const long serialVersionUID = 1L;

        private const int DEFAULT_BLOCK_SIZE = 32 * 1024; // 32 KB default size

        internal sealed class Block
#if FEATURE_CLONEABLE
            : System.ICloneable
#endif
        {
            internal const long serialVersionUID = 1L;

            internal readonly char[] chars;
            internal int length;

            internal Block(int size)
            {
                this.chars = new char[size];
                this.length = 0;
            }

            public object Clone()
            {
                var clone = new Block(chars.Length);
                clone.length = length;
                Array.Copy(chars, clone.chars, chars.Length);
                return clone;
            }

            

            // LUCENENET specific
            public void Serialize(Stream writer)
            {
                writer.Write(serialVersionUID); // Version of this object to use when deserializing
                writer.Write(chars.Length);
                writer.Write(chars);
                writer.Write(length);
            }

            // LUCENENET specific
            // Deserialization constructor
            public Block(Stream reader)
            {
                long serialVersion = reader.ReadInt64();

                switch (serialVersion)
                {
                    case serialVersionUID:
                        int charsLength = reader.ReadInt32();
                        this.chars = reader.ReadChars(charsLength);
                        this.length = reader.ReadInt32();
                        break;

                    // case 1L:
                    // LUCENENET TODO: When object fields change, increment serialVersionUID and move the above block here for legacy support...
                    default:
                        throw new InvalidDataException($"Version {serialVersion} of {this.GetType().ToString()} deserialization is not supported.");
                }
            }
        }

        internal IList<Block> blocks;
        internal Block current;
        internal int blockSize;
        internal int length;

        public CharBlockArray()
            : this(DEFAULT_BLOCK_SIZE)
        {
        }

        internal CharBlockArray(int blockSize)
        {
            this.blocks = new List<Block>();
            this.blockSize = blockSize;
            AddBlock();
        }

        private void AddBlock()
        {
            this.current = new Block(this.blockSize);
            this.blocks.Add(this.current);
        }

        internal virtual int BlockIndex(int index)
        {
            return index / blockSize;
        }

        internal virtual int IndexInBlock(int index)
        {
            return index % blockSize;
        }

        public virtual CharBlockArray Append(ICharSequence chars)
        {
            return Append(chars, 0, chars.Length);
        }

        public virtual CharBlockArray Append(char c)
        {
            if (this.current.length == this.blockSize)
            {
                AddBlock();
            }
            this.current.chars[this.current.length++] = c;
            this.length++;

            return this;
        }

        public virtual CharBlockArray Append(ICharSequence chars, int start, int length)
        {
            int end = start + length;
            for (int i = start; i < end; i++)
            {
                Append(chars[i]);
            }
            return this;
        }

        public virtual CharBlockArray Append(char[] chars, int start, int length)
        {
            int offset = start;
            int remain = length;
            while (remain > 0)
            {
                if (this.current.length == this.blockSize)
                {
                    AddBlock();
                }
                int toCopy = remain;
                int remainingInBlock = this.blockSize - this.current.length;
                if (remainingInBlock < toCopy)
                {
                    toCopy = remainingInBlock;
                }
                Array.Copy(chars, offset, this.current.chars, this.current.length, toCopy);
                offset += toCopy;
                remain -= toCopy;
                this.current.length += toCopy;
            }

            this.length += length;
            return this;
        }

        public virtual CharBlockArray Append(string s)
        {
            int remain = s.Length;
            int offset = 0;
            while (remain > 0)
            {
                if (this.current.length == this.blockSize)
                {
                    AddBlock();
                }
                int toCopy = remain;
                int remainingInBlock = this.blockSize - this.current.length;
                if (remainingInBlock < toCopy)
                {
                    toCopy = remainingInBlock;
                }
                s.CopyTo(offset, this.current.chars, this.current.length, toCopy);
                offset += toCopy;
                remain -= toCopy;
                this.current.length += toCopy;
            }

            this.length += s.Length;
            return this;
        }

        // LUCENENET specific - replaced with this[index]
        //public virtual char CharAt(int index)
        //{
        //    Block b = blocks[BlockIndex(index)];
        //    return b.chars[IndexInBlock(index)];
        //}

        // LUCENENET specific - added to .NETify
        public virtual char this[int index]
        {
            get
            {
                Block b = blocks[BlockIndex(index)];
                return b.chars[IndexInBlock(index)];
            }
        }

        public virtual int Length => this.length;


        // LUCENENET specific
        bool ICharSequence.HasValue => true;

        public virtual ICharSequence Subsequence(int startIndex, int length)
        {
            int remaining = length;
            StringBuilder sb = new StringBuilder(remaining);
            int blockIdx = BlockIndex(startIndex);
            int indexInBlock = IndexInBlock(startIndex);
            while (remaining > 0)
            {
                Block b = blocks[blockIdx++];
                int numToAppend = Math.Min(remaining, b.length - indexInBlock);
                sb.Append(b.chars, indexInBlock, numToAppend);
                remaining -= numToAppend;
                indexInBlock = 0; // 2nd+ iterations read from start of the block
            }
            return new StringBuilderCharSequence(sb);
        }

        ICharSequence ICharSequence.Subsequence(int startIndex, int length)
        {
            return Subsequence(startIndex, length);
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (Block b in blocks)
            {
                sb.Append(b.chars, 0, b.length);
            }
            return sb.ToString();
        }

        internal virtual void Flush(Stream @out)
        {
            @out.Write(serialVersionUID); // version of this object to use when deserializing
            @out.Write(blocks.Count);
            int currentIndex = 0;
            for (int i = 0; i < blocks.Count; i++)
            {
                var block = blocks[i];
                block.Serialize(@out);
                if (block == current)
                {
                    currentIndex = i;
                }
            }
            // Write the index of the current block so we can
            // set the reference when deserializing
            @out.Write(currentIndex);
            @out.Write(blockSize);
            @out.Write(length);
            @out.Flush();
        }

        // LUCENENET specific
        // Deserialization constructor
        internal CharBlockArray(Stream reader)
        {
            long serialVersion = reader.ReadInt64();

            switch (serialVersion)
            {
                case serialVersionUID:
                    var blocksCount = reader.ReadInt32();
                    this.blocks = new List<Block>(blocksCount);
                    for (int i = 0; i < blocksCount; i++)
                    {
                        blocks.Add(new Block(reader));
                    }
                    this.current = blocks[reader.ReadInt32()];
                    this.blockSize = reader.ReadInt32();
                    this.length = reader.ReadInt32();
                    break;

                // case 1L:
                // LUCENENET TODO: When object fields change, increment serialVersionUID and move the above block here for legacy support...
                default:
                    throw new InvalidDataException($"Version {serialVersion} of {this.GetType().ToString()} deserialization is not supported.");
            }
        }

        public static CharBlockArray Open(Stream @in)
        {
            return new CharBlockArray(@in);
        }
    }
}