// 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 "pw_hex_dump/hex_dump.h"

#include <array>
#include <cinttypes>
#include <cstdint>
#include <cstring>
#include <span>
#include <string_view>

#include "gtest/gtest.h"
#include "pw_log/log.h"

namespace pw::dump {
namespace {

std::array<const std::byte, 33> source_data = {
    std::byte(0xa4), std::byte(0xcc), std::byte(0x32), std::byte(0x62),
    std::byte(0x9b), std::byte(0x46), std::byte(0x38), std::byte(0x1a),
    std::byte(0x23), std::byte(0x1a), std::byte(0x2a), std::byte(0x7a),
    std::byte(0xbc), std::byte(0xe2), std::byte(0x40), std::byte(0xa0),
    std::byte(0xff), std::byte(0x33), std::byte(0xe5), std::byte(0x2b),
    std::byte(0x9e), std::byte(0x9f), std::byte(0x6b), std::byte(0x3c),
    std::byte(0xbe), std::byte(0x9b), std::byte(0x89), std::byte(0x3c),
    std::byte(0x7e), std::byte(0x4a), std::byte(0x7a), std::byte(0x48),
    std::byte(0x18)};

std::array<const std::byte, 15> short_string = {
    std::byte('m'),
    std::byte('y'),
    std::byte(' '),
    std::byte('t'),
    std::byte('e'),
    std::byte('s'),
    std::byte('t'),
    std::byte(' '),
    std::byte('s'),
    std::byte('t'),
    std::byte('r'),
    std::byte('i'),
    std::byte('n'),
    std::byte('g'),
    std::byte('\n'),
};

class HexDump : public ::testing::Test {
 protected:
  HexDump() { dumper_ = FormattedHexDumper(dest_, default_flags_); }

  // Sufficiently large destination buffer to hold line-by-line formatted hex
  // dump.
  std::array<char, 256> dest_ = {0};
  FormattedHexDumper dumper_;
  FormattedHexDumper::Flags default_flags_ = {
      .bytes_per_line = 16,
      .group_every = 1,
      .show_ascii = false,
      .show_header = false,
      .prefix_mode = FormattedHexDumper::AddressMode::kDisabled};
};

class SmallBuffer : public ::testing::Test {
 protected:
  SmallBuffer() {
    // Disable address prefix for most of the tests as it's platform-specific.
    dumper_ = FormattedHexDumper(dest_, default_flags_);
  }

  // Small destination buffer that should be inadequate in some cases.
  std::array<char, 7> dest_ = {0};
  FormattedHexDumper dumper_;
  FormattedHexDumper::Flags default_flags_ = {
      .bytes_per_line = 16,
      .group_every = 1,
      .show_ascii = false,
      .show_header = false,
      .prefix_mode = FormattedHexDumper::AddressMode::kDisabled};
};

// On platforms where uintptr_t is 32-bit this evaluates to a 10-byte string
// where hex_string is prefixed with "0x". On 64-bit targets, this expands to
// an 18-byte string with the significant bytes are zero padded.
#define EXPECTED_SIGNIFICANT_BYTES(hex_string)                    \
  sizeof(uintptr_t) == sizeof(uint64_t) ? "0x00000000" hex_string \
                                        : "0x" hex_string

TEST_F(HexDump, DumpAddr_ZeroSizeT) {
  constexpr const char* expected = EXPECTED_SIGNIFICANT_BYTES("00000000");
  size_t zero = 0;
  EXPECT_EQ(DumpAddr(dest_, zero), Status::Ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, DumpAddr_NonzeroSizeT) {
  constexpr const char* expected = EXPECTED_SIGNIFICANT_BYTES("deadbeef");
  size_t nonzero = 0xDEADBEEF;
  EXPECT_TRUE(DumpAddr(dest_, nonzero).ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, DumpAddr_ZeroPtr) {
  constexpr const char* expected = EXPECTED_SIGNIFICANT_BYTES("00000000");
  uintptr_t zero = 0;
  EXPECT_TRUE(DumpAddr(dest_, reinterpret_cast<const void*>(zero)).ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, DumpAddr_NonzeroPtr) {
  constexpr const char* expected = EXPECTED_SIGNIFICANT_BYTES("deadbeef");
  uintptr_t nonzero = 0xDEADBEEF;
  EXPECT_TRUE(DumpAddr(dest_, reinterpret_cast<const void*>(nonzero)).ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_Defaults) {
  constexpr const char* expected =
      "a4 cc 32 62 9b 46 38 1a 23 1a 2a 7a bc e2 40 a0  ..2b.F8.#.*z..@.";
  default_flags_.show_ascii = true;
  dumper_ = FormattedHexDumper(dest_, default_flags_);
  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_DefaultHeader) {
  constexpr const char* expected =
      " 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f";

  default_flags_.show_header = true;
  dumper_ = FormattedHexDumper(dest_, default_flags_);
  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_DumpEntireBuffer) {
  constexpr size_t kTestBytesPerLine = 8;

  default_flags_.bytes_per_line = kTestBytesPerLine;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  for (size_t i = 0; i < source_data.size(); i += kTestBytesPerLine) {
    EXPECT_TRUE(dumper_.DumpLine().ok());
  }
  EXPECT_EQ(dumper_.DumpLine(), Status::ResourceExhausted());
}

// This test is provided for convenience of debugging, as it actually logs the
// dump.
TEST_F(HexDump, FormattedHexDump_LogDump) {
  default_flags_.show_ascii = true;
  default_flags_.show_header = true;
  default_flags_.prefix_mode = FormattedHexDumper::AddressMode::kOffset;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  // Dump data.
  while (dumper_.DumpLine().ok()) {
    PW_LOG_INFO("%s", dest_.data());
  }
  EXPECT_EQ(dumper_.DumpLine(), Status::ResourceExhausted());
}

TEST_F(HexDump, FormattedHexDump_NoSpaces) {
  constexpr const char* expected = "a4cc32629b46381a231a2a7abce240a0";

  default_flags_.group_every = 0;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_SetGroupEveryByte) {
  constexpr const char* expected =
      "a4 cc 32 62 9b 46 38 1a 23 1a 2a 7a bc e2 40 a0";
  default_flags_.group_every = 1;
  dumper_ = FormattedHexDumper(dest_, default_flags_);
  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_SetGroupEveryThreeBytes) {
  constexpr const char* expected = "a4cc32 629b46 381a23 1a2a7a bce240 a0";

  default_flags_.group_every = 3;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_TwoLines) {
  constexpr const char* expected1 = "a4 cc 32 62 9b 46 38 1a";
  constexpr const char* expected2 = "23 1a 2a 7a bc e2 40 a0";

  default_flags_.bytes_per_line = 8;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  // Dump first line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected1, dest_.data());
  // Dump second line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected2, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_Ascii) {
  constexpr const char* expected1 = "6d 79 20 74 65 73 74 20  my test ";
  constexpr const char* expected2 = "73 74 72 69 6e 67 0a     string.";

  default_flags_.bytes_per_line = 8;
  default_flags_.show_ascii = true;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(short_string).ok());
  // Dump first line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected1, dest_.data());
  // Dump second line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected2, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_AsciiHeader) {
  constexpr const char* expected0 = " 0        4        Text";
  constexpr const char* expected1 = "6d792074 65737420  my test ";
  constexpr const char* expected2 = "73747269 6e670a    string.";

  default_flags_.bytes_per_line = 8;
  default_flags_.group_every = 4;
  default_flags_.show_ascii = true;
  default_flags_.show_header = true;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(short_string).ok());
  // Dump header.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected0, dest_.data());
  // Dump first line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected1, dest_.data());
  // Dump second line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected2, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_AsciiHeaderGroupEvery) {
  constexpr const char* expected0 = " 0  1  2  3  4  5  6  7  Text";
  constexpr const char* expected1 = "6d 79 20 74 65 73 74 20  my test ";
  constexpr const char* expected2 = "73 74 72 69 6e 67 0a     string.";

  default_flags_.bytes_per_line = 8;
  default_flags_.group_every = 1;
  default_flags_.show_ascii = true;
  default_flags_.show_header = true;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(short_string).ok());
  // Dump header.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected0, dest_.data());
  // Dump first line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected1, dest_.data());
  // Dump second line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected2, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_OffsetPrefix) {
  constexpr const char* expected1 = "0000";
  constexpr const char* expected2 = "0010";

  default_flags_.bytes_per_line = 16;
  default_flags_.prefix_mode = FormattedHexDumper::AddressMode::kOffset;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  // Dump first line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  // Truncate string to only contain the offset.
  dest_[strlen(expected1)] = '\0';
  EXPECT_STREQ(expected1, dest_.data());

  // Dump second line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  // Truncate string to only contain the offset.
  dest_[strlen(expected2)] = '\0';
  EXPECT_STREQ(expected2, dest_.data());
}

TEST_F(HexDump, FormattedHexDump_AbsolutePrefix) {
  constexpr size_t kTestBytesPerLine = 16;
  std::array<char, kHexAddrStringSize + 1> expected1;
  std::array<char, kHexAddrStringSize + 1> expected2;
  DumpAddr(expected1, source_data.data());
  DumpAddr(expected2, source_data.data() + kTestBytesPerLine);

  default_flags_.bytes_per_line = kTestBytesPerLine;
  default_flags_.prefix_mode = FormattedHexDumper::AddressMode::kAbsolute;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  // Dump first line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  // Truncate string to only contain the offset.
  dest_[kHexAddrStringSize] = '\0';
  EXPECT_STREQ(expected1.data(), dest_.data());

  // Dump second line.
  EXPECT_TRUE(dumper_.DumpLine().ok());
  // Truncate string to only contain the offset.
  dest_[kHexAddrStringSize] = '\0';
  EXPECT_STREQ(expected2.data(), dest_.data());
}

TEST_F(SmallBuffer, TinyHexDump) {
  constexpr const char* expected = "a4cc32";

  default_flags_.bytes_per_line = 3;
  default_flags_.group_every = 4;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_TRUE(dumper_.BeginDump(source_data).ok());
  EXPECT_TRUE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(SmallBuffer, TooManyBytesPerLine) {
  constexpr const char* expected = "";

  default_flags_.bytes_per_line = 13;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_EQ(dumper_.BeginDump(source_data), Status::FailedPrecondition());
  EXPECT_FALSE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(SmallBuffer, SpacesIncreaseBufferRequirement) {
  constexpr const char* expected = "";

  default_flags_.bytes_per_line = 3;
  default_flags_.group_every = 1;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_EQ(dumper_.BeginDump(source_data), Status::FailedPrecondition());
  EXPECT_FALSE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST_F(SmallBuffer, PrefixIncreasesBufferRequirement) {
  constexpr const char* expected = "";

  default_flags_.bytes_per_line = 3;
  default_flags_.prefix_mode = FormattedHexDumper::AddressMode::kOffset;
  dumper_ = FormattedHexDumper(dest_, default_flags_);

  EXPECT_EQ(dumper_.BeginDump(source_data), Status::FailedPrecondition());
  EXPECT_FALSE(dumper_.DumpLine().ok());
  EXPECT_STREQ(expected, dest_.data());
}

TEST(BadBuffer, ZeroSize) {
  char buffer[1] = {static_cast<char>(0xaf)};
  FormattedHexDumper dumper(std::span<char>(buffer, 0));
  EXPECT_EQ(dumper.BeginDump(source_data), Status::FailedPrecondition());
  EXPECT_EQ(dumper.DumpLine(), Status::FailedPrecondition());
  EXPECT_EQ(buffer[0], static_cast<char>(0xaf));
}

TEST(BadBuffer, NullPtrDest) {
  FormattedHexDumper dumper;
  EXPECT_EQ(dumper.SetLineBuffer(std::span<char>()), Status::InvalidArgument());
  EXPECT_EQ(dumper.BeginDump(source_data), Status::FailedPrecondition());
  EXPECT_EQ(dumper.DumpLine(), Status::FailedPrecondition());
}

TEST(BadBuffer, NullPtrSrc) {
  char buffer[24] = {static_cast<char>(0)};
  FormattedHexDumper dumper(buffer);
  EXPECT_EQ(dumper.BeginDump(ByteSpan(nullptr, 64)), Status::InvalidArgument());
  // Don't actually dump nullptr in this test as it could cause a crash.
}

}  // namespace
}  // namespace pw::dump
