// 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, size_t N = sizeof(T)> T ReadFixed(absl::string_view *data) {
  static_assert(N <= sizeof(N), "N too big for this data type");
  T val = 0;
  if (data->size() < N) {
    THROW("premature EOF reading fixed-length data");
  }
  memcpy(&val, data->data(), N);
  data->remove_prefix(N);
  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_
