//===- MsgPackReader.cpp - Simple MsgPack reader ----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
///  \file
///  This file implements a MessagePack reader.
///
//===----------------------------------------------------------------------===//

#include "llvm/BinaryFormat/MsgPackReader.h"
#include "llvm/BinaryFormat/MsgPack.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MathExtras.h"

using namespace llvm;
using namespace llvm::support;
using namespace msgpack;

Reader::Reader(MemoryBufferRef InputBuffer)
    : InputBuffer(InputBuffer), Current(InputBuffer.getBufferStart()),
      End(InputBuffer.getBufferEnd()) {}

Reader::Reader(StringRef Input) : Reader({Input, "MsgPack"}) {}

Expected<bool> Reader::read(Object &Obj) {
  if (Current == End)
    return false;

  uint8_t FB = static_cast<uint8_t>(*Current++);

  switch (FB) {
  case FirstByte::Nil:
    Obj.Kind = Type::Nil;
    return true;
  case FirstByte::True:
    Obj.Kind = Type::Boolean;
    Obj.Bool = true;
    return true;
  case FirstByte::False:
    Obj.Kind = Type::Boolean;
    Obj.Bool = false;
    return true;
  case FirstByte::Int8:
    Obj.Kind = Type::Int;
    return readInt<int8_t>(Obj);
  case FirstByte::Int16:
    Obj.Kind = Type::Int;
    return readInt<int16_t>(Obj);
  case FirstByte::Int32:
    Obj.Kind = Type::Int;
    return readInt<int32_t>(Obj);
  case FirstByte::Int64:
    Obj.Kind = Type::Int;
    return readInt<int64_t>(Obj);
  case FirstByte::UInt8:
    Obj.Kind = Type::UInt;
    return readUInt<uint8_t>(Obj);
  case FirstByte::UInt16:
    Obj.Kind = Type::UInt;
    return readUInt<uint16_t>(Obj);
  case FirstByte::UInt32:
    Obj.Kind = Type::UInt;
    return readUInt<uint32_t>(Obj);
  case FirstByte::UInt64:
    Obj.Kind = Type::UInt;
    return readUInt<uint64_t>(Obj);
  case FirstByte::Float32:
    Obj.Kind = Type::Float;
    if (sizeof(float) > remainingSpace())
      return make_error<StringError>(
          "Invalid Float32 with insufficient payload",
          std::make_error_code(std::errc::invalid_argument));
    Obj.Float = BitsToFloat(endian::read<uint32_t, Endianness>(Current));
    Current += sizeof(float);
    return true;
  case FirstByte::Float64:
    Obj.Kind = Type::Float;
    if (sizeof(double) > remainingSpace())
      return make_error<StringError>(
          "Invalid Float64 with insufficient payload",
          std::make_error_code(std::errc::invalid_argument));
    Obj.Float = BitsToDouble(endian::read<uint64_t, Endianness>(Current));
    Current += sizeof(double);
    return true;
  case FirstByte::Str8:
    Obj.Kind = Type::String;
    return readRaw<uint8_t>(Obj);
  case FirstByte::Str16:
    Obj.Kind = Type::String;
    return readRaw<uint16_t>(Obj);
  case FirstByte::Str32:
    Obj.Kind = Type::String;
    return readRaw<uint32_t>(Obj);
  case FirstByte::Bin8:
    Obj.Kind = Type::Binary;
    return readRaw<uint8_t>(Obj);
  case FirstByte::Bin16:
    Obj.Kind = Type::Binary;
    return readRaw<uint16_t>(Obj);
  case FirstByte::Bin32:
    Obj.Kind = Type::Binary;
    return readRaw<uint32_t>(Obj);
  case FirstByte::Array16:
    Obj.Kind = Type::Array;
    return readLength<uint16_t>(Obj);
  case FirstByte::Array32:
    Obj.Kind = Type::Array;
    return readLength<uint32_t>(Obj);
  case FirstByte::Map16:
    Obj.Kind = Type::Map;
    return readLength<uint16_t>(Obj);
  case FirstByte::Map32:
    Obj.Kind = Type::Map;
    return readLength<uint32_t>(Obj);
  case FirstByte::FixExt1:
    Obj.Kind = Type::Extension;
    return createExt(Obj, FixLen::Ext1);
  case FirstByte::FixExt2:
    Obj.Kind = Type::Extension;
    return createExt(Obj, FixLen::Ext2);
  case FirstByte::FixExt4:
    Obj.Kind = Type::Extension;
    return createExt(Obj, FixLen::Ext4);
  case FirstByte::FixExt8:
    Obj.Kind = Type::Extension;
    return createExt(Obj, FixLen::Ext8);
  case FirstByte::FixExt16:
    Obj.Kind = Type::Extension;
    return createExt(Obj, FixLen::Ext16);
  case FirstByte::Ext8:
    Obj.Kind = Type::Extension;
    return readExt<uint8_t>(Obj);
  case FirstByte::Ext16:
    Obj.Kind = Type::Extension;
    return readExt<uint16_t>(Obj);
  case FirstByte::Ext32:
    Obj.Kind = Type::Extension;
    return readExt<uint32_t>(Obj);
  }

  if ((FB & FixBitsMask::NegativeInt) == FixBits::NegativeInt) {
    Obj.Kind = Type::Int;
    int8_t I;
    static_assert(sizeof(I) == sizeof(FB), "Unexpected type sizes");
    memcpy(&I, &FB, sizeof(FB));
    Obj.Int = I;
    return true;
  }

  if ((FB & FixBitsMask::PositiveInt) == FixBits::PositiveInt) {
    Obj.Kind = Type::UInt;
    Obj.UInt = FB;
    return true;
  }

  if ((FB & FixBitsMask::String) == FixBits::String) {
    Obj.Kind = Type::String;
    uint8_t Size = FB & ~FixBitsMask::String;
    return createRaw(Obj, Size);
  }

  if ((FB & FixBitsMask::Array) == FixBits::Array) {
    Obj.Kind = Type::Array;
    Obj.Length = FB & ~FixBitsMask::Array;
    return true;
  }

  if ((FB & FixBitsMask::Map) == FixBits::Map) {
    Obj.Kind = Type::Map;
    Obj.Length = FB & ~FixBitsMask::Map;
    return true;
  }

  return make_error<StringError>(
      "Invalid first byte", std::make_error_code(std::errc::invalid_argument));
}

template <class T> Expected<bool> Reader::readRaw(Object &Obj) {
  if (sizeof(T) > remainingSpace())
    return make_error<StringError>(
        "Invalid Raw with insufficient payload",
        std::make_error_code(std::errc::invalid_argument));
  T Size = endian::read<T, Endianness>(Current);
  Current += sizeof(T);
  return createRaw(Obj, Size);
}

template <class T> Expected<bool> Reader::readInt(Object &Obj) {
  if (sizeof(T) > remainingSpace())
    return make_error<StringError>(
        "Invalid Int with insufficient payload",
        std::make_error_code(std::errc::invalid_argument));
  Obj.Int = static_cast<int64_t>(endian::read<T, Endianness>(Current));
  Current += sizeof(T);
  return true;
}

template <class T> Expected<bool> Reader::readUInt(Object &Obj) {
  if (sizeof(T) > remainingSpace())
    return make_error<StringError>(
        "Invalid Int with insufficient payload",
        std::make_error_code(std::errc::invalid_argument));
  Obj.UInt = static_cast<uint64_t>(endian::read<T, Endianness>(Current));
  Current += sizeof(T);
  return true;
}

template <class T> Expected<bool> Reader::readLength(Object &Obj) {
  if (sizeof(T) > remainingSpace())
    return make_error<StringError>(
        "Invalid Map/Array with invalid length",
        std::make_error_code(std::errc::invalid_argument));
  Obj.Length = static_cast<size_t>(endian::read<T, Endianness>(Current));
  Current += sizeof(T);
  return true;
}

template <class T> Expected<bool> Reader::readExt(Object &Obj) {
  if (sizeof(T) > remainingSpace())
    return make_error<StringError>(
        "Invalid Ext with invalid length",
        std::make_error_code(std::errc::invalid_argument));
  T Size = endian::read<T, Endianness>(Current);
  Current += sizeof(T);
  return createExt(Obj, Size);
}

Expected<bool> Reader::createRaw(Object &Obj, uint32_t Size) {
  if (Size > remainingSpace())
    return make_error<StringError>(
        "Invalid Raw with insufficient payload",
        std::make_error_code(std::errc::invalid_argument));
  Obj.Raw = StringRef(Current, Size);
  Current += Size;
  return true;
}

Expected<bool> Reader::createExt(Object &Obj, uint32_t Size) {
  if (Current == End)
    return make_error<StringError>(
        "Invalid Ext with no type",
        std::make_error_code(std::errc::invalid_argument));
  Obj.Extension.Type = *Current++;
  if (Size > remainingSpace())
    return make_error<StringError>(
        "Invalid Ext with insufficient payload",
        std::make_error_code(std::errc::invalid_argument));
  Obj.Extension.Bytes = StringRef(Current, Size);
  Current += Size;
  return true;
}
