// Copyright 2020 The Pigweed Authors
//
// 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
//
//     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.

// Utilities for building std::byte arrays from strings or integer values at
// compile time.
#pragma once

#include <array>
#include <cstddef>
#include <iterator>

namespace pw::bytes {
namespace internal {

template <typename T>
constexpr bool UseBytesDirectly = std::is_integral_v<T> || std::is_enum_v<T>;

// Internal implementation functions. CopyBytes copies bytes from an array of
// byte-sized elements or the underlying bytes of an integer (as little-endian).
// std::memcpy cannot be used since it is not constexpr.
template <typename B, typename T, typename... Args>
consteval void CopyBytes(B* array, T value, Args... args) {
  static_assert(sizeof(B) == sizeof(std::byte));

  if constexpr (UseBytesDirectly<T>) {
    if constexpr (sizeof(T) == 1u) {
      *array++ = static_cast<B>(value);
    } else {
      for (size_t i = 0; i < sizeof(T); ++i) {
        *array++ = static_cast<B>(value & 0xFF);
        value >>= 8;
      }
    }
  } else {
    static_assert(sizeof(value[0]) == sizeof(B));
    for (auto b : value) {
      *array++ = static_cast<B>(b);
    }
  }

  if constexpr (sizeof...(args) > 0u) {
    CopyBytes(array, args...);
  }
}

// Evaluates to the size in bytes of an integer or byte array.
template <typename T>
consteval size_t SizeOfBytes(const T& arg) {
  if constexpr (UseBytesDirectly<T>) {
    return sizeof(arg);
  } else {
    static_assert(sizeof(arg[0]) == sizeof(std::byte));
    return std::size(arg);
  }
}

template <typename B, typename T, size_t... kIndex>
consteval auto String(const T& array, std::index_sequence<kIndex...>) {
  return std::array{static_cast<B>(array[kIndex])...};
}

template <typename T, typename U>
consteval bool CanBeRepresentedAsByteType(const U& value) {
  return static_cast<U>(static_cast<T>(value)) == value;
}

}  // namespace internal

// Concatenates arrays or integers as a byte array at compile time. Integer
// values are copied little-endian. Spans are copied byte-for-byte.
template <typename B = std::byte, typename... Args>
consteval auto Concat(Args... args) {
  std::array<B, (internal::SizeOfBytes(args) + ...)> bytes{};
  internal::CopyBytes(bytes.begin(), args...);
  return bytes;
}

// Converts a string literal to an array of bytes, without the trailing '\0'.
template <typename B = std::byte,
          size_t kSize,
          typename Indices = std::make_index_sequence<kSize - 1>>
consteval auto String(const char (&str)[kSize]) {
  return internal::String<B>(str, Indices{});
}

// String overload for the empty string "".
template <typename B = std::byte>
consteval auto String(const char (&)[1]) {
  return std::array<B, 0>{};
}

// Creates an array of bytes from values passed as template parameters. The
// values are guaranteed to be representable in the destination byte type.
template <typename B, auto... values>
consteval auto Array() {
  static_assert((internal::CanBeRepresentedAsByteType<B>(values) && ...));
  return std::array<B, sizeof...(values)>{static_cast<B>(values)...};
}

// Array() defaults to using std::byte.
template <auto... values>
consteval auto Array() {
  return Array<std::byte, values...>();
}

// Creates an initialized array of bytes. Initializes the array to a value or
// the return values from a function that accepts the index as a parameter.
template <typename B, size_t kSize, typename T>
constexpr auto Initialized(const T& value_or_function) {
  std::array<B, kSize> array{};

  for (size_t i = 0; i < kSize; ++i) {
    if constexpr (std::is_integral_v<T>) {
      array[i] = static_cast<B>(value_or_function);
    } else {
      array[i] = static_cast<B>(value_or_function(i));
    }
  }
  return array;
}

// Initialized(value_or_function) defaults to using std::byte.
template <size_t kSize, typename T>
constexpr auto Initialized(const T& value_or_function) {
  return Initialized<std::byte, kSize>(value_or_function);
}

// Creates an array of bytes from a series of function arguments. Unlike
// Array(), MakeArray() cannot check if the values fit in the destination type.
// MakeArray() should only be used when Array() is not suitable.
template <typename B = std::byte, typename... Args>
constexpr auto MakeArray(const Args&... args) {
  return std::array<B, sizeof...(args)>{static_cast<B>(args)...};
}

}  // namespace pw::bytes
