// 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.
#pragma once

#include <cstdarg>
#include <cstddef>
#include <cstring>
#include <span>

#include "pw_tokenizer/config.h"
#include "pw_tokenizer/internal/argument_types.h"
#include "pw_tokenizer/tokenize.h"

namespace pw {
namespace tokenizer {

// Encodes a tokenized string's arguments to a buffer. The
// pw_tokenizer_ArgTypes parameter specifies the argument types, in place of a
// format string.
//
// Most tokenization implementations may use the EncodedMessage class below.
size_t EncodeArgs(pw_tokenizer_ArgTypes types,
                  va_list args,
                  std::span<std::byte> output);

// Encodes a tokenized message to a fixed size buffer. The size of the buffer is
// determined by the PW_TOKENIZER_CFG_ENCODING_BUFFER_SIZE_BYTES config macro.
//
// This class is used to encode tokenized messages passed in from the
// tokenization macros. The macros provided by pw_tokenizer use this class, and
// projects that elect to define their own versions of the tokenization macros
// should use it when possible.
//
// To use the pw::Tokenizer::EncodedMessage, construct it with the token,
// argument types, and va_list from the variadic arguments:
//
//   void SendLogMessage(std::span<std::byte> log_data);
//
//   extern "C" void TokenizeToSendLogMessage(pw_tokenizer_Token token,
//                                            pw_tokenizer_ArgTypes types,
//                                            ...) {
//     va_list args;
//     va_start(args, types);
//     EncodedMessage encoded_message(token, types, args);
//     va_end(args);
//
//     SendLogMessage(encoded_message);  // EncodedMessage converts to std::span
//   }
//
class EncodedMessage {
 public:
  // Encodes a tokenized message to an internal buffer.
  EncodedMessage(pw_tokenizer_Token token,
                 pw_tokenizer_ArgTypes types,
                 va_list args) {
    std::memcpy(data_, &token, sizeof(token));
    args_size_ = EncodeArgs(
        types, args, std::span<std::byte>(data_).subspan(sizeof(token)));
  }

  // The binary-encoded tokenized message.
  const std::byte* data() const { return data_; }

  // Returns the data() as a pointer to uint8_t instead of std::byte.
  const uint8_t* data_as_uint8() const {
    return reinterpret_cast<const uint8_t*>(data());
  }

  // The size of the encoded tokenized message in bytes.
  size_t size() const { return sizeof(pw_tokenizer_Token) + args_size_; }

 private:
  std::byte data_[PW_TOKENIZER_CFG_ENCODING_BUFFER_SIZE_BYTES];
  size_t args_size_;
};

static_assert(PW_TOKENIZER_CFG_ENCODING_BUFFER_SIZE_BYTES >=
                  sizeof(pw_tokenizer_Token),
              "PW_TOKENIZER_CFG_ENCODING_BUFFER_SIZE_BYTES must be at least "
              "large enough for a token (4 bytes)");

}  // namespace tokenizer
}  // namespace pw
