﻿// 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.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Apache.Arrow.Memory;

namespace Apache.Arrow
{
    public partial struct ArrowBuffer
    {
        /// <summary>
        /// The <see cref="BitmapBuilder"/> class is a complement to <see cref="ArrowBuffer.Builder{T}"/>
        /// and is designed for boolean fields, which are efficiently bit-packed into byte-aligned memory.
        /// </summary>
        public class BitmapBuilder
        {
            private const int DefaultBitCapacity = 64;

            /// <summary>
            /// Gets the number of bits that can be contained in the memory allocated by the current instance.
            /// </summary>
            public int Capacity { get; private set; }

            /// <summary>
            /// Gets the number of bits currently appended.
            /// </summary>
            public int Length { get; private set; }

            /// <summary>
            /// Gets the raw byte memory underpinning the builder.
            /// </summary>
            public Memory<byte> Memory { get; private set; }

            /// <summary>
            /// Gets the span of (bit-packed byte) memory underpinning the builder.
            /// </summary>
            public Span<byte> Span => Memory.Span;

            /// <summary>
            /// Gets the number of set bits (i.e. set to 1).
            /// </summary>
            public int SetBitCount { get; private set; }

            /// <summary>
            /// Gets the number of unset bits (i.e. set to 0).
            /// </summary>
            public int UnsetBitCount => Length - SetBitCount;

            /// <summary>
            /// Creates an instance of the <see cref="BitmapBuilder"/> class.
            /// </summary>
            /// <param name="capacity">Number of bits of initial capacity to reserve.</param>
            public BitmapBuilder(int capacity = DefaultBitCapacity)
            {
                Memory = new byte[BitUtility.ByteCount(capacity)];
                Capacity = capacity;
            }

            /// <summary>
            /// Append a single bit.
            /// </summary>
            /// <param name="value">Bit to append.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Append(bool value)
            {
                if (Length % 8 == 0)
                {
                    // Append a new byte to the buffer when needed.
                    EnsureAdditionalCapacity(1);
                }

                BitUtility.SetBit(Span, Length, value);
                Length++;
                SetBitCount += value ? 1 : 0;
                return this;
            }

            /// <summary>
            /// Append a span of bits.
            /// </summary>
            /// <param name="source">Source of bits to append.</param>
            /// <param name="validBits">Number of valid bits in the source span.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Append(ReadOnlySpan<byte> source, int validBits)
            {
                if (!source.IsEmpty && validBits > source.Length * 8)
                    throw new ArgumentException($"Number of valid bits ({validBits}) cannot be greater than the source span length ({source.Length * 8} bits).", nameof(validBits));

                // Check if memory copy can be used from the source array (performance optimization for byte-aligned coping)
                if (!source.IsEmpty && Length % 8 == 0)
                {
                    EnsureAdditionalCapacity(validBits);
                    source.Slice(0, BitUtility.ByteCount(validBits)).CopyTo(Span.Slice(Length / 8));

                    Length += validBits;
                    SetBitCount += BitUtility.CountBits(source, 0, validBits);
                }
                else
                {
                    for (int i = 0; i < validBits; i++)
                    {
                        Append(source.IsEmpty || BitUtility.GetBit(source, i));
                    }
                }

                return this;
            }

            /// <summary>
            /// Append multiple bits.
            /// </summary>
            /// <param name="values">Bits to append.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder AppendRange(IEnumerable<bool> values)
            {
                if (values != null)
                {
                    foreach (var v in values)
                    {
                        Append(v);
                    }
                }

                return this;
            }

            /// <summary>
            /// Append multiple bits.
            /// </summary>
            /// <param name="value">Value of bits to append.</param>
            /// <param name="length">Number of times the value should be added.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder AppendRange(bool value, int length)
            {
                if (length < 0)
                    throw new ArgumentOutOfRangeException(nameof(length));

                EnsureAdditionalCapacity(length);
                Span<byte> span = Span;
                BitUtility.SetBits(span, Length, length, value);

                Length += length;
                SetBitCount += value ? length : 0;

                return this;
            }

            /// <summary>
            /// Toggle the bit at a particular index.
            /// </summary>
            /// <param name="index">Index of bit to toggle.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Toggle(int index)
            {
                CheckIndex(index);
                bool priorValue = BitUtility.GetBit(Span, index);
                SetBitCount += priorValue ? -1 : 1;
                BitUtility.ToggleBit(Span, index);
                return this;
            }

            /// <summary>
            /// Set the bit at a particular index to 1.
            /// </summary>
            /// <param name="index">Index of bit to set.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Set(int index)
            {
                CheckIndex(index);
                bool priorValue = BitUtility.GetBit(Span, index);
                SetBitCount += priorValue ? 0 : 1;
                BitUtility.SetBit(Span, index);
                return this;
            }

            /// <summary>
            /// Set the bit at a particular index to a given value.
            /// </summary>
            /// <param name="index">Index of bit to set/unset.</param>
            /// <param name="value">Value of bit.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Set(int index, bool value)
            {
                CheckIndex(index);
                bool priorValue = BitUtility.GetBit(Span, index);
                SetBitCount -= priorValue ? 1 : 0;
                SetBitCount += value ? 1 : 0;
                BitUtility.SetBit(Span, index, value);
                return this;
            }

            /// <summary>
            /// Swap the bits at two given indices.
            /// </summary>
            /// <param name="i">First index.</param>
            /// <param name="j">Second index.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Swap(int i, int j)
            {
                CheckIndex(i);
                CheckIndex(j);
                bool bi = BitUtility.GetBit(Span, i);
                bool bj = BitUtility.GetBit(Span, j);
                BitUtility.SetBit(Span, i, bj);
                BitUtility.SetBit(Span, j, bi);
                return this;
            }

            /// <summary>
            /// Reserve a given number of bits' additional capacity.
            /// </summary>
            /// <param name="additionalCapacity">Number of bits of required additional capacity.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Reserve(int additionalCapacity)
            {
                if (additionalCapacity < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(additionalCapacity));
                }

                EnsureAdditionalCapacity(additionalCapacity);
                return this;
            }

            /// <summary>
            /// Resize the buffer to a given size.
            /// </summary>
            /// <remarks>
            /// Note that if the required capacity is larger than the current length of the populated buffer so far,
            /// the buffer's contents in the new, expanded region are undefined.
            /// </remarks>
            /// <remarks>
            /// Note that if the required capacity is smaller than the current length of the populated buffer so far,
            /// the buffer will be truncated and items at the end of the buffer will be lost.
            /// </remarks>
            /// <param name="capacity">Number of bits of required capacity.</param>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Resize(int capacity)
            {
                if (capacity < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(capacity), "Capacity must be non-negative");
                }

                EnsureCapacity(capacity);
                Length = capacity;

                SetBitCount = BitUtility.CountBits(Span, 0, Length);

                return this;
            }

            /// <summary>
            /// Clear all contents appended so far.
            /// </summary>
            /// <returns>Returns the builder (for fluent-style composition).</returns>
            public BitmapBuilder Clear()
            {
                Span.Fill(default);
                Length = 0;
                SetBitCount = 0;
                return this;
            }

            /// <summary>
            /// Build an Arrow buffer from the appended contents so far.
            /// </summary>
            /// <param name="allocator">Optional memory allocator.</param>
            /// <returns>Returns an <see cref="ArrowBuffer"/> object.</returns>
            public ArrowBuffer Build(MemoryAllocator allocator = default)
            {
                int bufferLength = checked((int)BitUtility.RoundUpToMultipleOf64(Memory.Length));
                var memoryAllocator = allocator ?? MemoryAllocator.Default.Value;
                var memoryOwner = memoryAllocator.Allocate(bufferLength);
                Memory.Slice(0, Memory.Length).CopyTo(memoryOwner.Memory);
                return new ArrowBuffer(memoryOwner);
            }

            private void CheckIndex(int index)
            {
                if (index < 0 || index >= Length)
                {
                    throw new ArgumentOutOfRangeException(nameof(index));
                }
            }

            private void EnsureAdditionalCapacity(int additionalCapacity)
            {
                EnsureCapacity(checked(Length + additionalCapacity));
            }

            private void EnsureCapacity(int requiredCapacity)
            {
                if (requiredCapacity > Capacity)
                {
                    // TODO: specifiable growth strategy
                    // Double the length of the in-memory array, or use the byte count of the capacity, whichever is
                    // greater.
                    int byteCount = Math.Max(BitUtility.ByteCount(requiredCapacity), Memory.Length * 2);
                    Reallocate(byteCount);
                    Capacity = byteCount * 8;
                }
            }

            private void Reallocate(int numBytes)
            {
                if (numBytes != 0)
                {
                    Debug.Assert(numBytes > Memory.Length);
                    var memory = new Memory<byte>(new byte[numBytes]);
                    Memory.CopyTo(memory);

                    Memory = memory;
                }
            }
        }
    }
}
