/*
 * 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
 *
 *     https://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.Buffers;
using System.Buffers.Binary;
using System.Text;

namespace Avro.IO
{
    /// <content>
    /// Contains the netstandard2.1 and netcoreapp2.1 specific functionality for BinaryDecoder.
    /// </content>
    public partial class BinaryDecoder
    {
        private const int StackallocThreshold = 256;

        /// <summary>
        /// A float is written as 4 bytes.
        /// The float is converted into a 32-bit integer using a method equivalent to
        /// Java's floatToIntBits and then encoded in little-endian format.
        /// </summary>
        /// <returns></returns>
        public float ReadFloat()
        {
            Span<byte> buffer = stackalloc byte[4];
            Read(buffer);

            return BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(buffer));
        }

        /// <summary>
        /// A double is written as 8 bytes.
        /// The double is converted into a 64-bit integer using a method equivalent to
        /// Java's doubleToLongBits and then encoded in little-endian format.
        /// </summary>
        /// <returns>A double value.</returns>
        public double ReadDouble()
        {
            Span<byte> buffer = stackalloc byte[8];
            Read(buffer);

            return BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(buffer));
        }

        /// <summary>
        /// Reads a string written by <see cref="BinaryEncoder.WriteString(string)"/>.
        /// </summary>
        /// <returns>String read from the stream.</returns>
        public string ReadString()
        {
            byte[] bufferArray = null;

            int length = ReadInt();
            Span<byte> buffer = length <= StackallocThreshold ?
                stackalloc byte[length] :
                (bufferArray = ArrayPool<byte>.Shared.Rent(length)).AsSpan(0, length);

            Read(buffer);

            string result = Encoding.UTF8.GetString(buffer);

            if (bufferArray != null)
            {
                ArrayPool<byte>.Shared.Return(bufferArray);
            }

            return result;
        }

        private void Read(byte[] buffer, int start, int len)
        {
            Read(buffer.AsSpan(start, len));
        }

        private void Read(Span<byte> buffer)
        {
            while (!buffer.IsEmpty)
            {
                int n = stream.Read(buffer);
                if (n <= 0) throw new AvroException("End of stream reached");
                buffer = buffer.Slice(n);
            }
        }
    }
}
