// 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.

// This file provides functions for working with the prefixed Base64 format for
// tokenized messages. This format is useful for transmitting tokenized messages
// as plain text.
//
// The format uses a prefix character ($), followed by the Base64 version of the
// tokenized message. For example, consider a tokenized message with token
// 0xfeb35a42 and encoded argument 0x13. This messsage would be encoded as
// follows:
//
//            Binary: 42 5a b3 fe 13  [5 bytes]
//
//   Prefixed Base64: $Qlqz/hM=       [9 bytes]
//
#pragma once

#include <stddef.h>

#include "pw_preprocessor/util.h"
#include "pw_tokenizer/config.h"
#include "pw_tokenizer/nested_tokenization.h"

PW_EXTERN_C_START

// Encodes a binary tokenized message as prefixed Base64 with a null terminator.
// Returns the encoded string length (excluding the null terminator). Returns 0
// if the buffer is too small. Always null terminates if the output buffer is
// not empty.
//
// Equivalent to pw::tokenizer::PrefixedBase64Encode.
size_t pw_tokenizer_PrefixedBase64Encode(const void* binary_message,
                                         size_t binary_size_bytes,
                                         void* output_buffer,
                                         size_t output_buffer_size_bytes);

// Decodes a prefixed Base64 tokenized message to binary. Returns the size of
// the decoded binary data. The resulting data is ready to be passed to
// pw::tokenizer::Detokenizer::Detokenize. Returns 0 if the buffer is too small,
// the expected prefix character is missing, or the Base64 data is corrupt.
//
// Equivalent to pw::tokenizer::PrefixedBase64Encode.
size_t pw_tokenizer_PrefixedBase64Decode(const void* base64_message,
                                         size_t base64_size_bytes,
                                         void* output_buffer,
                                         size_t output_buffer_size);

PW_EXTERN_C_END

#ifdef __cplusplus

#include <string_view>

#include "pw_base64/base64.h"
#include "pw_span/span.h"
#include "pw_tokenizer/config.h"
#include "pw_tokenizer/tokenize.h"

namespace pw::tokenizer {

// Returns the size of a tokenized message (token + arguments) when encoded as
// prefixed Base64. Includes room for the prefix character ($) and encoded
// message. This value is the capacity needed to encode to a pw::InlineString.
constexpr size_t Base64EncodedStringSize(size_t message_size) {
  return sizeof(PW_TOKENIZER_NESTED_PREFIX) + base64::EncodedSize(message_size);
}

// Same as Base64EncodedStringSize(), but for sizing char buffers. Includes room
// for the prefix character ($), encoded message, and a null terminator.
constexpr size_t Base64EncodedBufferSize(size_t message_size) {
  return Base64EncodedStringSize(message_size) + sizeof('\0');
}

// Encodes a binary tokenized message as prefixed Base64 with a null terminator.
// Returns the encoded string length (excluding the null terminator). Returns 0
// if the buffer is too small. Always null terminates if the output buffer is
// not empty.
inline size_t PrefixedBase64Encode(span<const std::byte> binary_message,
                                   span<char> output_buffer) {
  return pw_tokenizer_PrefixedBase64Encode(binary_message.data(),
                                           binary_message.size(),
                                           output_buffer.data(),
                                           output_buffer.size());
}

// Also accept a span<const uint8_t> for the binary message.
inline size_t PrefixedBase64Encode(span<const uint8_t> binary_message,
                                   span<char> output_buffer) {
  return PrefixedBase64Encode(as_bytes(binary_message), output_buffer);
}

// Encodes a binary tokenized message as prefixed Base64 to a pw::InlineString,
// appending to any existing contents. Asserts if the message does not fit in
// the string.
void PrefixedBase64Encode(span<const std::byte> binary_message,
                          InlineString<>& output);

inline void PrefixedBase64Encode(span<const uint8_t> binary_message,
                                 InlineString<>& output) {
  return PrefixedBase64Encode(as_bytes(binary_message), output);
}

// Encodes a binary tokenized message as prefixed Base64 to a pw::InlineString.
// The pw::InlineString is sized to fit messages up to
// kMaxBinaryMessageSizeBytes long. Asserts if the message is larger.
template <size_t kMaxBinaryMessageSizeBytes>
auto PrefixedBase64Encode(span<const std::byte> binary_message) {
  static_assert(kMaxBinaryMessageSizeBytes >= 1, "Messages cannot be empty");
  InlineString<Base64EncodedStringSize(kMaxBinaryMessageSizeBytes)> string(
      1, PW_TOKENIZER_NESTED_PREFIX);
  base64::Encode(binary_message, string);
  return string;
}

template <size_t kMaxBinaryMessageSizeBytes>
auto PrefixedBase64Encode(span<const uint8_t> binary_message) {
  return PrefixedBase64Encode<kMaxBinaryMessageSizeBytes>(
      as_bytes(binary_message));
}

// Decodes a prefixed Base64 tokenized message to binary. Returns the size of
// the decoded binary data. The resulting data is ready to be passed to
// pw::tokenizer::Detokenizer::Detokenize.
inline size_t PrefixedBase64Decode(std::string_view base64_message,
                                   span<std::byte> output_buffer) {
  return pw_tokenizer_PrefixedBase64Decode(base64_message.data(),
                                           base64_message.size(),
                                           output_buffer.data(),
                                           output_buffer.size());
}

// Decodes a prefixed Base64 tokenized message to binary in place. Returns the
// size of the decoded binary data.
inline size_t PrefixedBase64DecodeInPlace(span<std::byte> buffer) {
  return pw_tokenizer_PrefixedBase64Decode(
      buffer.data(), buffer.size(), buffer.data(), buffer.size());
}

inline size_t PrefixedBase64DecodeInPlace(span<char> buffer) {
  return PrefixedBase64DecodeInPlace(as_writable_bytes(buffer));
}

// Decodes a prefixed Base64 tokenized message to binary in place. Resizes the
// string to fit the decoded binary data.
template <typename CharT>
inline void PrefixedBase64DecodeInPlace(InlineBasicString<CharT>& string) {
  static_assert(sizeof(CharT) == sizeof(char));
  string.resize(pw_tokenizer_PrefixedBase64Decode(
      string.data(), string.size(), string.data(), string.size()));
}

}  // namespace pw::tokenizer

#endif  // __cplusplus
