// Copyright 2016 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>

#include <limits>
#include <memory>

#include "core/fxcodec/basic/basicmodule.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/base/cxx17_backports.h"

TEST(fxcodec, A85TestBadInputs) {
  const uint8_t src_buf[] = {1, 2, 3, 4};
  std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
  uint32_t dest_size = 0;

  // Error codes, not segvs, should callers pass us a nullptr pointer.
  EXPECT_FALSE(BasicModule::A85Encode(src_buf, &dest_buf, nullptr));
  EXPECT_FALSE(BasicModule::A85Encode(src_buf, nullptr, &dest_size));
  EXPECT_FALSE(BasicModule::A85Encode({}, &dest_buf, &dest_size));
}

// No leftover bytes, just translate 2 sets of symbols.
TEST(fxcodec, A85TestBasic) {
  // Make sure really big values don't break.
  const uint8_t src_buf[] = {1, 2, 3, 4, 255, 255, 255, 255};
  std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
  uint32_t dest_size = 0;
  EXPECT_TRUE(BasicModule::A85Encode(src_buf, &dest_buf, &dest_size));

  // Should have 5 chars for each set of 4 and 2 terminators.
  const uint8_t expected_out[] = {33, 60, 78, 63, 43,  115,
                                  56, 87, 45, 33, 126, 62};
  ASSERT_EQ(pdfium::size(expected_out), dest_size);

  // Check the output
  auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
  for (uint32_t i = 0; i < dest_size; i++)
    EXPECT_EQ(expected_out[i], dest_buf_span[i]) << " at " << i;
}

// Leftover bytes.
TEST(fxcodec, A85TestLeftoverBytes) {
  std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
  uint32_t dest_size = 0;

  {
    // 1 Leftover Byte:
    const uint8_t src_buf_1leftover[] = {1, 2, 3, 4, 255};
    EXPECT_TRUE(
        BasicModule::A85Encode(src_buf_1leftover, &dest_buf, &dest_size));

    // 5 chars for first symbol + 2 + 2 terminators.
    uint8_t expected_out_1leftover[] = {33, 60, 78, 63, 43, 114, 114, 126, 62};
    ASSERT_EQ(pdfium::size(expected_out_1leftover), dest_size);

    // Check the output
    auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
    for (uint32_t i = 0; i < dest_size; i++)
      EXPECT_EQ(expected_out_1leftover[i], dest_buf_span[i]) << " at " << i;
  }

  {
    // 2 Leftover bytes:
    const uint8_t src_buf_2leftover[] = {1, 2, 3, 4, 255, 254};
    dest_buf.reset();
    dest_size = 0;
    EXPECT_TRUE(
        BasicModule::A85Encode(src_buf_2leftover, &dest_buf, &dest_size));
    // 5 chars for first symbol + 3 + 2 terminators.
    const uint8_t expected_out_2leftover[] = {33,  60, 78, 63,  43,
                                              115, 56, 68, 126, 62};
    ASSERT_EQ(pdfium::size(expected_out_2leftover), dest_size);

    // Check the output
    auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
    for (uint32_t i = 0; i < dest_size; i++)
      EXPECT_EQ(expected_out_2leftover[i], dest_buf_span[i]) << " at " << i;
  }

  {
    // 3 Leftover bytes:
    const uint8_t src_buf_3leftover[] = {1, 2, 3, 4, 255, 254, 253};
    dest_buf.reset();
    dest_size = 0;
    EXPECT_TRUE(
        BasicModule::A85Encode(src_buf_3leftover, &dest_buf, &dest_size));
    // 5 chars for first symbol + 4 + 2 terminators.
    const uint8_t expected_out_3leftover[] = {33, 60, 78,  63,  43, 115,
                                              56, 77, 114, 126, 62};
    ASSERT_EQ(pdfium::size(expected_out_3leftover), dest_size);

    // Check the output
    auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
    for (uint32_t i = 0; i < dest_size; i++)
      EXPECT_EQ(expected_out_3leftover[i], dest_buf_span[i]) << " at " << i;
  }
}

// Test all zeros comes through as "z".
TEST(fxcodec, A85TestZeros) {
  std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
  uint32_t dest_size = 0;

  {
    // Make sure really big values don't break.
    const uint8_t src_buf[] = {1, 2, 3, 4, 0, 0, 0, 0};
    EXPECT_TRUE(BasicModule::A85Encode(src_buf, &dest_buf, &dest_size));

    // Should have 5 chars for first set of 4 + 1 for z + 2 terminators.
    const uint8_t expected_out[] = {33, 60, 78, 63, 43, 122, 126, 62};
    ASSERT_EQ(pdfium::size(expected_out), dest_size);

    // Check the output
    auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
    for (uint32_t i = 0; i < dest_size; i++)
      EXPECT_EQ(expected_out[i], dest_buf_span[i]) << " at " << i;
  }

  {
    // Should also work if it is at the start:
    const uint8_t src_buf_2[] = {0, 0, 0, 0, 1, 2, 3, 4};
    dest_buf.reset();
    dest_size = 0;
    EXPECT_TRUE(BasicModule::A85Encode(src_buf_2, &dest_buf, &dest_size));

    // Should have 5 chars for set of 4 + 1 for z + 2 terminators.
    const uint8_t expected_out_2[] = {122, 33, 60, 78, 63, 43, 126, 62};
    ASSERT_EQ(pdfium::size(expected_out_2), dest_size);

    // Check the output
    auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
    for (uint32_t i = 0; i < dest_size; i++)
      EXPECT_EQ(expected_out_2[i], dest_buf_span[i]) << " at " << i;
  }

  {
    // Try with 2 leftover zero bytes. Make sure we don't get a "z".
    const uint8_t src_buf_3[] = {1, 2, 3, 4, 0, 0};
    dest_buf.reset();
    dest_size = 0;
    EXPECT_TRUE(BasicModule::A85Encode(src_buf_3, &dest_buf, &dest_size));

    // Should have 5 chars for set of 4 + 3 for last 2 + 2 terminators.
    const uint8_t expected_out_leftover[] = {33, 60, 78, 63,  43,
                                             33, 33, 33, 126, 62};
    ASSERT_EQ(pdfium::size(expected_out_leftover), dest_size);

    // Check the output
    auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
    for (uint32_t i = 0; i < dest_size; i++)
      EXPECT_EQ(expected_out_leftover[i], dest_buf_span[i]) << " at " << i;
  }
}

// Make sure we get returns in the expected locations.
TEST(fxcodec, A85TestLineBreaks) {
  // Make sure really big values don't break.
  uint8_t src_buf[131] = {0};
  // 1 full line + most of a line of normal symbols.
  for (int k = 0; k < 116; k += 4) {
    src_buf[k] = 1;
    src_buf[k + 1] = 2;
    src_buf[k + 2] = 3;
    src_buf[k + 3] = 4;
  }
  // Fill in the end, leaving an all zero gap + 3 extra zeros at the end.
  for (int k = 120; k < 128; k++) {
    src_buf[k] = 1;
    src_buf[k + 1] = 2;
    src_buf[k + 2] = 3;
    src_buf[k + 3] = 4;
  }
  std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
  uint32_t dest_size = 0;

  // Should succeed.
  EXPECT_TRUE(BasicModule::A85Encode(src_buf, &dest_buf, &dest_size));

  // Should have 75 chars in the first row plus 2 char return,
  // 76 chars in the second row plus 2 char return,
  // and 9 chars in the last row with 2 terminators.
  ASSERT_EQ(166u, dest_size);

  // Check for the returns.
  auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
  EXPECT_EQ(13, dest_buf_span[75]);
  EXPECT_EQ(10, dest_buf_span[76]);
  EXPECT_EQ(13, dest_buf_span[153]);
  EXPECT_EQ(10, dest_buf_span[154]);
}
