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

#include <algorithm>
#include <array>

#include "gtest/gtest.h"
#include "pw_tokenizer/tokenize.h"

namespace pw {
namespace tokenizer {
namespace {

template <size_t kSize>
uint32_t TestHash(const char (&str)[kSize]) {
  static_assert(kSize > 0u, "Must have at least a null terminator");

  static constexpr uint32_t k65599HashConstant = 65599u;

  // The length is hashed as if it were the first character.
  uint32_t hash = kSize - 1;
  uint32_t coefficient = k65599HashConstant;

  size_t length =
      std::min(static_cast<size_t>(PW_TOKENIZER_CFG_HASH_LENGTH), kSize - 1);

  // Hash all of the characters in the string as unsigned ints.
  for (size_t i = 0; i < length; ++i) {
    hash += coefficient * str[i];
    coefficient *= k65599HashConstant;
  }

  return hash;
}

TEST(TokenizeStringLiteral, EmptyString_IsZero) {
  constexpr pw_TokenizerStringToken token = PW_TOKENIZE_STRING("");
  EXPECT_TRUE(0u == token);
}

TEST(TokenizeStringLiteral, String_MatchesHash) {
  constexpr uint32_t token = PW_TOKENIZE_STRING("[:-)");
  EXPECT_TRUE(TestHash("[:-)") == token);
}

constexpr uint32_t kGlobalToken = PW_TOKENIZE_STRING(">:-[]");

TEST(TokenizeStringLiteral, GlobalVariable_MatchesHash) {
  EXPECT_TRUE(TestHash(">:-[]") == kGlobalToken);
}

class TokenizeToBuffer : public ::testing::Test {
 public:
  TokenizeToBuffer() : buffer_{} {}

 protected:
  uint8_t buffer_[64];
};

// Test fixture for callback and global handler. Both of these need a global
// message buffer. To keep the message buffers separate, template this on the
// derived class type.
template <typename Impl>
class GlobalMessage : public ::testing::Test {
 public:
  static void SetMessage(const uint8_t* message, size_t size) {
    ASSERT_TRUE(size <= sizeof(message_));
    std::memcpy(message_, message, size);
    message_size_bytes_ = size;
  }

 protected:
  GlobalMessage() {
    std::memset(message_, 0, sizeof(message_));
    message_size_bytes_ = 0;
  }

  static uint8_t message_[256];
  static size_t message_size_bytes_;
};

template <typename Impl>
uint8_t GlobalMessage<Impl>::message_[256] = {};
template <typename Impl>
size_t GlobalMessage<Impl>::message_size_bytes_ = 0;

class TokenizeToCallback : public GlobalMessage<TokenizeToCallback> {};

template <uint8_t... kData, size_t kSize>
std::array<uint8_t, sizeof(uint32_t) + sizeof...(kData)> ExpectedData(
    const char (&format)[kSize]) {
  const uint32_t value = TestHash(format);
  return std::array<uint8_t, sizeof(uint32_t) + sizeof...(kData)>{
      static_cast<uint8_t>(value & 0xff),
      static_cast<uint8_t>(value >> 8 & 0xff),
      static_cast<uint8_t>(value >> 16 & 0xff),
      static_cast<uint8_t>(value >> 24 & 0xff),
      kData...};
}

TEST_F(TokenizeToCallback, Variety) {
  PW_TOKENIZE_TO_CALLBACK(
      SetMessage, "%s there are %x (%.2f) of them%c", "Now", 2u, 2.0f, '.');
  const auto expected =  // clang-format off
      ExpectedData<3, 'N', 'o', 'w',        // string "Now"
                   0x04,                    // unsigned 2 (zig-zag encoded)
                   0x00, 0x00, 0x00, 0x40,  // float 2.0
                   0x5C                     // char '.' (0x2E, zig-zag encoded)
                   >("%s there are %x (%.2f) of them%c");
  // clang-format on
  ASSERT_TRUE(expected.size() == message_size_bytes_);
  EXPECT_TRUE(std::memcmp(expected.data(), message_, expected.size()) == 0);
}

#if PW_TOKENIZER_CFG_ENABLE_TOKENIZE_TO_GLOBAL_HANDLER

class TokenizeToGlobalHandler : public GlobalMessage<TokenizeToGlobalHandler> {
};

TEST_F(TokenizeToGlobalHandler, Variety) {
  PW_TOKENIZE_TO_GLOBAL_HANDLER("%x%lld%1.2f%s", 0, 0ll, -0.0, "");
  const auto expected =
      ExpectedData<0, 0, 0x00, 0x00, 0x00, 0x80, 0>("%x%lld%1.2f%s");
  ASSERT_TRUE(expected.size() == message_size_bytes_);
  EXPECT_TRUE(std::memcmp(expected.data(), message_, expected.size()) == 0);
}

extern "C" void pw_TokenizerHandleEncodedMessage(const uint8_t* encoded_message,
                                                 size_t size_bytes) {
  TokenizeToGlobalHandler::SetMessage(encoded_message, size_bytes);
}

#endif  // PW_TOKENIZER_CFG_ENABLE_TOKENIZE_TO_GLOBAL_HANDLER

#if PW_TOKENIZER_CFG_ENABLE_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD

class TokenizeToGlobalHandlerWithPayload
    : public GlobalMessage<TokenizeToGlobalHandlerWithPayload> {
 public:
  static void SetPayload(pw_TokenizerPayload payload) {
    payload_ = reinterpret_cast<intptr_t>(payload);
  }

 protected:
  TokenizeToGlobalHandlerWithPayload() { payload_ = {}; }

  static intptr_t payload_;
};

intptr_t TokenizeToGlobalHandlerWithPayload::payload_;

TEST_F(TokenizeToGlobalHandlerWithPayload, Variety) {
  ASSERT_TRUE(payload_ != 123);

  const auto expected =
      ExpectedData<0, 0, 0x00, 0x00, 0x00, 0x80, 0>("%x%lld%1.2f%s");

  PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
      reinterpret_cast<pw_TokenizerPayload>(123),
      "%x%lld%1.2f%s",
      0,
      0ll,
      -0.0,
      "");
  ASSERT_TRUE(expected.size() == message_size_bytes_);
  EXPECT_TRUE(std::memcmp(expected.data(), message_, expected.size()) == 0);
  EXPECT_TRUE(payload_ == 123);

  PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
      reinterpret_cast<pw_TokenizerPayload>(-543),
      "%x%lld%1.2f%s",
      0,
      0ll,
      -0.0,
      "");
  ASSERT_TRUE(expected.size() == message_size_bytes_);
  EXPECT_TRUE(std::memcmp(expected.data(), message_, expected.size()) == 0);
  EXPECT_TRUE(payload_ == -543);
}

extern "C" void pw_TokenizerHandleEncodedMessageWithPayload(
    pw_TokenizerPayload payload,
    const uint8_t* encoded_message,
    size_t size_bytes) {
  TokenizeToGlobalHandlerWithPayload::SetMessage(encoded_message, size_bytes);
  TokenizeToGlobalHandlerWithPayload::SetPayload(payload);
}

#endif  // PW_TOKENIZER_CFG_ENABLE_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD

}  // namespace
}  // namespace tokenizer
}  // namespace pw
