// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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.

#ifndef BLOATY_UTIL_H_
#define BLOATY_UTIL_H_

#include <stdexcept>

#include "absl/numeric/int128.h"
#include "absl/strings/string_view.h"

namespace bloaty {

class Error : public std::runtime_error {
 public:
  Error(const char* msg, const char* file, int line)
      : std::runtime_error(msg), file_(file), line_(line) {}

  // TODO(haberman): add these to Bloaty's error message when verbose is
  // enabled.
  const char* file() const { return file_; }
  int line() const { return line_; }

 private:
  const char* file_;
  int line_;
};

// Throwing emits a lot of code, so we do it out-of-line.
ABSL_ATTRIBUTE_NORETURN
void Throw(const char *str, int line);

#define THROW(msg) Throw(msg, __LINE__)
#define THROWF(...) Throw(absl::Substitute(__VA_ARGS__).c_str(), __LINE__)
#define WARN(...)                                                   \
  if (verbose_level > 0) {                                          \
    printf("WARNING: %s\n", absl::Substitute(__VA_ARGS__).c_str()); \
  }

#if !defined(_MSC_VER)
#define BLOATY_UNREACHABLE() do { \
  assert(false); \
  __builtin_unreachable(); \
} while (0)
#else
#define BLOATY_UNREACHABLE() do { \
  assert(false); \
  __assume(0); \
} while (0)
#endif

#ifdef NDEBUG
// Prevent "unused variable" warnings.
#define BLOATY_ASSERT(expr) do {} while (false && (expr))
#else
#define BLOATY_ASSERT(expr) assert(expr)
#endif

inline uint64_t CheckedAdd(uint64_t a, uint64_t b) {
  absl::uint128 a_128(a), b_128(b);
  absl::uint128 c_128 = a_128 + b_128;
  if (c_128 > UINT64_MAX) {
    THROW("integer overflow in addition");
  }
  return static_cast<uint64_t>(c_128);
}

inline uint64_t CheckedMul(uint64_t a, uint64_t b) {
  absl::uint128 a_128(a), b_128(b);
  absl::uint128 c = a_128 * b_128;
  if (c > UINT64_MAX) {
    THROW("integer overflow in multiply");
  }
  return static_cast<uint64_t>(c);
}

inline absl::string_view StrictSubstr(absl::string_view data, size_t off,
                                      size_t n) {
  uint64_t end = CheckedAdd(off, n);
  if (end > data.size()) {
    THROW("region out-of-bounds");
  }
  return data.substr(off, n);
}

inline absl::string_view StrictSubstr(absl::string_view data, size_t off) {
  if (off > data.size()) {
    THROW("region out-of-bounds");
  }
  return data.substr(off);
}

inline size_t AlignUp(size_t offset, size_t granularity) {
  // Granularity must be a power of two.
  BLOATY_ASSERT((granularity & (granularity - 1)) == 0);
  return (offset + granularity - 1) & ~(granularity - 1);
}

// Endianness utilities ////////////////////////////////////////////////////////

enum class Endian { kBig, kLittle };

inline Endian GetMachineEndian() {
  int x = 1;
  return *(char *)&x == 1 ? Endian::kLittle : Endian::kBig;
}

// Generic algorithm for byte-swapping an integer of arbitrary size.
//
// With modern GCC/Clang this optimizes to a "bswap" instruction.
template <size_t N, class T> constexpr T _BS(T val) {
  if constexpr (N == 1) {
    return val & 0xff;
  } else {
    size_t bits = 8 * (N / 2);
    return (_BS<N / 2>(val) << bits) | _BS<N / 2>(val >> bits);
  }
};

// Byte swaps the given integer, and returns the byte-swapped value.
template <class T> constexpr T ByteSwap(T val) {
    return _BS<sizeof(T)>(val);
}

template <class T> T ReadFixed(absl::string_view *data) {
  T val;
  if (data->size() < sizeof(T)) {
    THROW("premature EOF reading fixed-length data");
  }
  memcpy(&val, data->data(), sizeof(T));
  data->remove_prefix(sizeof(T));
  return val;
}

template <class T> T ReadEndian(absl::string_view *data, Endian endian) {
  T val = ReadFixed<T>(data);
  return endian == GetMachineEndian() ? val : ByteSwap(val);
}

template <class T> T ReadLittleEndian(absl::string_view *data) {
  return ReadEndian<T>(data, Endian::kLittle);
}

template <class T> T ReadBigEndian(absl::string_view *data) {
  return ReadEndian<T>(data, Endian::kBig);
}

// General data reading  ///////////////////////////////////////////////////////

absl::string_view ReadNullTerminated(absl::string_view* data);

inline absl::string_view ReadBytes(size_t bytes, absl::string_view* data) {
  if (data->size() < bytes) {
    THROW("premature EOF reading variable-length DWARF data");
  }
  absl::string_view ret = data->substr(0, bytes);
  data->remove_prefix(bytes);
  return ret;
}

inline void SkipBytes(size_t bytes, absl::string_view* data) {
  ReadBytes(bytes, data);  // Discard result.
}

}  // namespace bloaty

#endif  // BLOATY_UTIL_H_
