/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed 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.
 */

#include "wabt/binary-reader-stats.h"

#include <cassert>
#include <cinttypes>
#include <cstdarg>
#include <cstdint>
#include <cstdio>

#include "wabt/binary-reader-nop.h"
#include "wabt/common.h"
#include "wabt/literal.h"
#include "wabt/stream.h"

namespace wabt {

OpcodeInfo::OpcodeInfo(Opcode opcode, Kind kind)
    : opcode_(opcode), kind_(kind) {}

template <typename T>
OpcodeInfo::OpcodeInfo(Opcode opcode, Kind kind, T* data, size_t count)
    : OpcodeInfo(opcode, kind) {
  if (count > 0) {
    data_.resize(sizeof(T) * count);
    memcpy(data_.data(), data, data_.size());
  }
}

template <typename T>
OpcodeInfo::OpcodeInfo(Opcode opcode, Kind kind, T* data, size_t count, T extra)
    : OpcodeInfo(opcode, kind, data, count) {
  data_.resize(data_.size() + sizeof(T));
  memcpy(data_.data() + data_.size() - sizeof(T), &extra, sizeof(T));
}

template <typename T>
std::pair<const T*, size_t> OpcodeInfo::GetDataArray() const {
  if (data_.empty()) {
    return std::pair<const T*, size_t>(nullptr, 0);
  }

  assert(data_.size() % sizeof(T) == 0);
  return std::make_pair(reinterpret_cast<const T*>(data_.data()),
                        data_.size() / sizeof(T));
}

template <typename T>
const T* OpcodeInfo::GetData(size_t expected_size) const {
  auto [data, size] = GetDataArray<T>();
  assert(size == expected_size);
  return data;
}

template <typename T, typename F>
void OpcodeInfo::WriteArray(Stream& stream, F&& write_func) {
  auto [data, size] = GetDataArray<T>();
  for (size_t i = 0; i < size; ++i) {
    // Write an initial space (to separate from the opcode name) first, then
    // comma-separate.
    stream.Writef("%s", i == 0 ? " " : ", ");
    write_func(data[i]);
  }
}

void OpcodeInfo::Write(Stream& stream) {
  stream.Writef("%s", opcode_.GetName());

  switch (kind_) {
    case Kind::Bare:
      break;

    case Kind::Uint32:
      stream.Writef(" %u (0x%x)", *GetData<uint32_t>(), *GetData<uint32_t>());
      break;

    case Kind::Uint64:
      stream.Writef(" %" PRIu64 " (0x%" PRIx64 ")", *GetData<uint64_t>(),
                    *GetData<uint64_t>());
      break;

    case Kind::Index:
      stream.Writef(" %" PRIindex, *GetData<Index>());
      break;

    case Kind::Float32: {
      stream.Writef(" %g", *GetData<float>());
      char buffer[WABT_MAX_FLOAT_HEX + 1];
      WriteFloatHex(buffer, sizeof(buffer), *GetData<uint32_t>());
      stream.Writef(" (%s)", buffer);
      break;
    }

    case Kind::Float64: {
      stream.Writef(" %g", *GetData<double>());
      char buffer[WABT_MAX_DOUBLE_HEX + 1];
      WriteDoubleHex(buffer, sizeof(buffer), *GetData<uint64_t>());
      stream.Writef(" (%s)", buffer);
      break;
    }

    case Kind::V128: {
      auto data = *GetData<v128>();
      auto l0 = data.u32(0);
      auto l1 = data.u32(1);
      auto l2 = data.u32(2);
      auto l3 = data.u32(3);
      stream.Writef(" %u %u %u %u (0x%x 0x%x 0x%x 0x%x)", l0, l1, l2, l3, l0,
                    l1, l2, l3);
      break;
    }

    case Kind::Uint32Uint32:
    case Kind::Uint32Uint32Uint32:
    case Kind::Uint32Uint32Uint32Uint32:
      WriteArray<uint32_t>(
          stream, [&stream](uint32_t value) { stream.Writef("%u", value); });
      break;

    case Kind::BlockSig: {
      auto type = *GetData<Type>();
      if (type.IsIndex()) {
        stream.Writef(" type:%d", type.GetIndex());
      } else if (type != Type::Void) {
        stream.Writef(" %s", type.GetName().c_str());
      }
      break;
    }

    case Kind::BrTable: {
      WriteArray<Index>(stream, [&stream](Index index) {
        stream.Writef("%" PRIindex, index);
      });
      break;
    }
  }
}

bool operator==(const OpcodeInfo& lhs, const OpcodeInfo& rhs) {
  return lhs.opcode_ == rhs.opcode_ && lhs.kind_ == rhs.kind_ &&
         lhs.data_ == rhs.data_;
}

bool operator!=(const OpcodeInfo& lhs, const OpcodeInfo& rhs) {
  return !(lhs == rhs);
}

bool operator<(const OpcodeInfo& lhs, const OpcodeInfo& rhs) {
  if (lhs.opcode_ < rhs.opcode_) {
    return true;
  }
  if (lhs.opcode_ > rhs.opcode_) {
    return false;
  }
  if (lhs.kind_ < rhs.kind_) {
    return true;
  }
  if (lhs.kind_ > rhs.kind_) {
    return false;
  }
  if (lhs.data_ < rhs.data_) {
    return true;
  }
  if (lhs.data_ > rhs.data_) {
    return false;
  }
  return false;
}

bool operator<=(const OpcodeInfo& lhs, const OpcodeInfo& rhs) {
  return lhs < rhs || lhs == rhs;
}

bool operator>(const OpcodeInfo& lhs, const OpcodeInfo& rhs) {
  return !(lhs <= rhs);
}

bool operator>=(const OpcodeInfo& lhs, const OpcodeInfo& rhs) {
  return !(lhs < rhs);
}

namespace {

class BinaryReaderOpcnt : public BinaryReaderNop {
 public:
  explicit BinaryReaderOpcnt(OpcodeInfoCounts* counts);

  Result OnOpcode(Opcode opcode) override;
  Result OnOpcodeBare() override;
  Result OnOpcodeUint32(uint32_t value) override;
  Result OnOpcodeIndex(Index value) override;
  Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) override;
  Result OnOpcodeUint32Uint32Uint32(uint32_t value,
                                    uint32_t value2,
                                    uint32_t value3) override;
  Result OnOpcodeUint64(uint64_t value) override;
  Result OnOpcodeF32(uint32_t value) override;
  Result OnOpcodeF64(uint64_t value) override;
  Result OnOpcodeV128(v128 value) override;
  Result OnOpcodeBlockSig(Type sig_type) override;
  Result OnBrTableExpr(Index num_targets,
                       Index* target_depths,
                       Index default_target_depth) override;
  Result OnEndExpr() override;

 private:
  template <typename... Args>
  Result Emplace(Args&&... args);

  OpcodeInfoCounts* opcode_counts_;
  Opcode current_opcode_;
};

template <typename... Args>
Result BinaryReaderOpcnt::Emplace(Args&&... args) {
  auto pair = opcode_counts_->emplace(
      std::piecewise_construct, std::make_tuple(std::forward<Args>(args)...),
      std::make_tuple(0));

  auto& count = pair.first->second;
  count++;
  return Result::Ok;
}

BinaryReaderOpcnt::BinaryReaderOpcnt(OpcodeInfoCounts* counts)
    : opcode_counts_(counts) {}

Result BinaryReaderOpcnt::OnOpcode(Opcode opcode) {
  current_opcode_ = opcode;
  return Result::Ok;
}

Result BinaryReaderOpcnt::OnOpcodeBare() {
  return Emplace(current_opcode_, OpcodeInfo::Kind::Bare);
}

Result BinaryReaderOpcnt::OnOpcodeUint32(uint32_t value) {
  return Emplace(current_opcode_, OpcodeInfo::Kind::Uint32, &value);
}

Result BinaryReaderOpcnt::OnOpcodeIndex(Index value) {
  return Emplace(current_opcode_, OpcodeInfo::Kind::Index, &value);
}

Result BinaryReaderOpcnt::OnOpcodeUint32Uint32(uint32_t value0,
                                               uint32_t value1) {
  uint32_t array[2] = {value0, value1};
  return Emplace(current_opcode_, OpcodeInfo::Kind::Uint32Uint32, array, 2);
}

Result BinaryReaderOpcnt::OnOpcodeUint32Uint32Uint32(uint32_t value0,
                                                     uint32_t value1,
                                                     uint32_t value2) {
  uint32_t array[3] = {value0, value1, value2};
  return Emplace(current_opcode_, OpcodeInfo::Kind::Uint32Uint32Uint32, array,
                 3);
}

Result BinaryReaderOpcnt::OnOpcodeUint64(uint64_t value) {
  return Emplace(current_opcode_, OpcodeInfo::Kind::Uint64, &value);
}

Result BinaryReaderOpcnt::OnOpcodeF32(uint32_t value) {
  return Emplace(current_opcode_, OpcodeInfo::Kind::Float32, &value);
}

Result BinaryReaderOpcnt::OnOpcodeF64(uint64_t value) {
  return Emplace(current_opcode_, OpcodeInfo::Kind::Float64, &value);
}

Result BinaryReaderOpcnt::OnOpcodeV128(v128 value) {
  return Emplace(current_opcode_, OpcodeInfo::Kind::V128, &value);
}

Result BinaryReaderOpcnt::OnOpcodeBlockSig(Type sig_type) {
  return Emplace(current_opcode_, OpcodeInfo::Kind::BlockSig, &sig_type);
}

Result BinaryReaderOpcnt::OnBrTableExpr(Index num_targets,
                                        Index* target_depths,
                                        Index default_target_depth) {
  return Emplace(current_opcode_, OpcodeInfo::Kind::BrTable, target_depths,
                 num_targets, default_target_depth);
}

Result BinaryReaderOpcnt::OnEndExpr() {
  return Emplace(Opcode::End, OpcodeInfo::Kind::Bare);
}

}  // end anonymous namespace

Result ReadBinaryOpcnt(const void* data,
                       size_t size,
                       const ReadBinaryOptions& options,
                       OpcodeInfoCounts* counts) {
  BinaryReaderOpcnt reader(counts);
  return ReadBinary(data, size, &reader, options);
}

}  // namespace wabt
