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

#include "core/fpdfapi/parser/cpdf_hint_tables.h"

#include <memory>
#include <string>
#include <utility>

#include "core/fpdfapi/page/test_with_page_module.h"
#include "core/fpdfapi/parser/cpdf_data_avail.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_linearized_header.h"
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fpdfapi/parser/cpdf_read_validator.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/cfx_read_only_string_stream.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/fx_stream.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/utils/path_service.h"

namespace {

RetainPtr<CPDF_ReadValidator> MakeValidatorFromFile(
    const std::string& file_name) {
  std::string file_path = PathService::GetTestFilePath(file_name);
  CHECK(!file_path.empty());
  return pdfium::MakeRetain<CPDF_ReadValidator>(
      IFX_SeekableReadStream::CreateFromFilename(file_path.c_str()), nullptr);
}

std::unique_ptr<CPDF_DataAvail> MakeDataAvailFromFile(
    const std::string& file_name) {
  return std::make_unique<CPDF_DataAvail>(nullptr,
                                          MakeValidatorFromFile(file_name));
}

class TestLinearizedHeader final : public CPDF_LinearizedHeader {
 public:
  TestLinearizedHeader(const CPDF_Dictionary* pDict,
                       FX_FILESIZE szLastXRefOffset)
      : CPDF_LinearizedHeader(pDict, szLastXRefOffset) {}

  static std::unique_ptr<CPDF_LinearizedHeader> MakeHeader(
      ByteString inline_data) {
    CPDF_SyntaxParser parser(
        pdfium::MakeRetain<CFX_ReadOnlyStringStream>(std::move(inline_data)));
    RetainPtr<CPDF_Dictionary> dict =
        ToDictionary(parser.GetObjectBody(nullptr));
    DCHECK(dict);
    return std::make_unique<TestLinearizedHeader>(dict.Get(), 0);
  }
};

}  // namespace

// Needs page module for encoding Hint table stream.
using HintTablesTest = TestWithPageModule;

TEST_F(HintTablesTest, Load) {
  auto data_avail = MakeDataAvailFromFile("feature_linearized_loading.pdf");
  ASSERT_EQ(CPDF_DataAvail::kDataAvailable, data_avail->IsDocAvail(nullptr));

  ASSERT_TRUE(data_avail->GetHintTablesForTest());

  const CPDF_HintTables* hint_tables = data_avail->GetHintTablesForTest();
  FX_FILESIZE page_start = 0;
  FX_FILESIZE page_length = 0;
  uint32_t page_obj_num = 0;

  ASSERT_TRUE(
      hint_tables->GetPagePos(0, &page_start, &page_length, &page_obj_num));
  EXPECT_EQ(777, page_start);
  EXPECT_EQ(4328, page_length);
  EXPECT_EQ(39u, page_obj_num);

  ASSERT_TRUE(
      hint_tables->GetPagePos(1, &page_start, &page_length, &page_obj_num));
  EXPECT_EQ(5105, page_start);
  EXPECT_EQ(767, page_length);
  EXPECT_EQ(1u, page_obj_num);

  ASSERT_FALSE(
      hint_tables->GetPagePos(2, &page_start, &page_length, &page_obj_num));
}

TEST_F(HintTablesTest, PageAndGroupInfos) {
  auto data_avail = MakeDataAvailFromFile("feature_linearized_loading.pdf");
  ASSERT_EQ(CPDF_DataAvail::kDataAvailable, data_avail->IsDocAvail(nullptr));

  const CPDF_HintTables* hint_tables = data_avail->GetHintTablesForTest();
  ASSERT_TRUE(hint_tables);
  ASSERT_EQ(2u, hint_tables->PageInfos().size());

  EXPECT_EQ(5u, hint_tables->PageInfos()[0].objects_count());
  EXPECT_EQ(777, hint_tables->PageInfos()[0].page_offset());
  EXPECT_EQ(4328u, hint_tables->PageInfos()[0].page_length());
  EXPECT_EQ(39u, hint_tables->PageInfos()[0].start_obj_num());
  ASSERT_EQ(2u, hint_tables->PageInfos()[0].Identifiers().size());

  EXPECT_EQ(0u, hint_tables->PageInfos()[0].Identifiers()[0]);
  EXPECT_EQ(0u, hint_tables->PageInfos()[0].Identifiers()[1]);

  EXPECT_EQ(3u, hint_tables->PageInfos()[1].objects_count());
  EXPECT_EQ(5105, hint_tables->PageInfos()[1].page_offset());
  EXPECT_EQ(767u, hint_tables->PageInfos()[1].page_length());
  EXPECT_EQ(1u, hint_tables->PageInfos()[1].start_obj_num());
  ASSERT_EQ(3u, hint_tables->PageInfos()[1].Identifiers().size());

  EXPECT_EQ(2u, hint_tables->PageInfos()[1].Identifiers()[0]);
  EXPECT_EQ(5u, hint_tables->PageInfos()[1].Identifiers()[1]);
  EXPECT_EQ(3u, hint_tables->PageInfos()[1].Identifiers()[2]);

  // SharedGroupInfo
  ASSERT_EQ(6u, hint_tables->SharedGroupInfos().size());

  EXPECT_EQ(777, hint_tables->SharedGroupInfos()[0].m_szOffset);
  EXPECT_EQ(254u, hint_tables->SharedGroupInfos()[0].m_dwLength);
  EXPECT_EQ(39u, hint_tables->SharedGroupInfos()[0].m_dwStartObjNum);
  EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[0].m_dwObjectsCount);

  EXPECT_EQ(1031, hint_tables->SharedGroupInfos()[1].m_szOffset);
  EXPECT_EQ(389u, hint_tables->SharedGroupInfos()[1].m_dwLength);
  EXPECT_EQ(40u, hint_tables->SharedGroupInfos()[1].m_dwStartObjNum);
  EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[1].m_dwObjectsCount);

  EXPECT_EQ(1420, hint_tables->SharedGroupInfos()[2].m_szOffset);
  EXPECT_EQ(726u, hint_tables->SharedGroupInfos()[2].m_dwLength);
  EXPECT_EQ(41u, hint_tables->SharedGroupInfos()[2].m_dwStartObjNum);
  EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[2].m_dwObjectsCount);

  EXPECT_EQ(2146, hint_tables->SharedGroupInfos()[3].m_szOffset);
  EXPECT_EQ(290u, hint_tables->SharedGroupInfos()[3].m_dwLength);
  EXPECT_EQ(42u, hint_tables->SharedGroupInfos()[3].m_dwStartObjNum);
  EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[3].m_dwObjectsCount);

  EXPECT_EQ(2436, hint_tables->SharedGroupInfos()[4].m_szOffset);
  EXPECT_EQ(2669u, hint_tables->SharedGroupInfos()[4].m_dwLength);
  EXPECT_EQ(43u, hint_tables->SharedGroupInfos()[4].m_dwStartObjNum);
  EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[4].m_dwObjectsCount);

  EXPECT_EQ(10939, hint_tables->SharedGroupInfos()[5].m_szOffset);
  EXPECT_EQ(544u, hint_tables->SharedGroupInfos()[5].m_dwLength);
  EXPECT_EQ(4u, hint_tables->SharedGroupInfos()[5].m_dwStartObjNum);
  EXPECT_EQ(1u, hint_tables->SharedGroupInfos()[5].m_dwObjectsCount);
}

TEST_F(HintTablesTest, FirstPageOffset) {
  // Test that valid hint table is loaded, and have correct offset of first page
  // object.
  const auto linearized_header = TestLinearizedHeader::MakeHeader(
      "<< /Linearized 1 /L 19326762 /H [ 123730 3816 ] /O 5932 /E 639518 /N "
      "102 /T 19220281 >>");
  ASSERT_TRUE(linearized_header);
  // This hint table is extracted from linearized file, generated by qpdf tool.
  RetainPtr<CPDF_ReadValidator> validator =
      MakeValidatorFromFile("hint_table_102p.bin");
  CPDF_SyntaxParser parser(validator, 0);
  RetainPtr<CPDF_Stream> stream = ToStream(parser.GetObjectBody(nullptr));
  ASSERT_TRUE(stream);
  auto hint_tables = std::make_unique<CPDF_HintTables>(validator.Get(),
                                                       linearized_header.get());
  // Check that hint table will load.
  ASSERT_TRUE(hint_tables->LoadHintStream(stream.Get()));
  // Check that hint table have correct first page offset.
  // 127546 is predefined real value from original file.
  EXPECT_EQ(127546, hint_tables->GetFirstPageObjOffset());
}
