// Copyright 2023 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/fpdfdoc/cpdf_annotlist.h"

#include <stdint.h>

#include <initializer_list>
#include <memory>

#include "constants/annotation_common.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/page/test_with_page_module.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/parser/cpdf_test_document.h"
#include "core/fpdfdoc/cpdf_annot.h"
#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/widestring.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class CPDFAnnotListTest : public TestWithPageModule {
 public:
  void SetUp() override {
    TestWithPageModule::SetUp();

    document_ = std::make_unique<CPDF_TestDocument>();
    document_->SetRoot(pdfium::MakeRetain<CPDF_Dictionary>());
    page_ = pdfium::MakeRetain<CPDF_Page>(
        document_.get(), pdfium::MakeRetain<CPDF_Dictionary>());
  }

  void TearDown() override {
    page_.Reset();
    document_.reset();

    TestWithPageModule::TearDown();
  }

 protected:
  void AddTextAnnotation(const ByteString& contents) {
    RetainPtr<CPDF_Dictionary> annotation =
        page_->GetOrCreateAnnotsArray()->AppendNew<CPDF_Dictionary>();
    annotation->SetNewFor<CPDF_Name>(pdfium::annotation::kSubtype, "Text");
    annotation->SetNewFor<CPDF_String>(pdfium::annotation::kContents, contents);
  }

  std::unique_ptr<CPDF_TestDocument> document_;
  RetainPtr<CPDF_Page> page_;
};

ByteString MakeByteString(std::initializer_list<uint8_t> bytes) {
  return ByteString(std::data(bytes), std::size(bytes));
}

ByteString GetRawContents(const CPDF_Annot* annotation) {
  return annotation->GetAnnotDict()->GetByteStringFor(
      pdfium::annotation::kContents);
}

WideString GetDecodedContents(const CPDF_Annot* annotation) {
  return annotation->GetAnnotDict()->GetUnicodeTextFor(
      pdfium::annotation::kContents);
}

}  // namespace

TEST_F(CPDFAnnotListTest, CreatePopupAnnotFromPdfEncoded) {
  const ByteString kContents = MakeByteString({'A', 'a', 0xE4, 0xA0});
  AddTextAnnotation(kContents);

  CPDF_AnnotList list(page_);

  ASSERT_EQ(2u, list.Count());
  EXPECT_EQ(kContents, GetRawContents(list.GetAt(1)));
  EXPECT_EQ(WideString::FromUTF8("Aaä€"), GetDecodedContents(list.GetAt(1)));
}

TEST_F(CPDFAnnotListTest, CreatePopupAnnotFromUnicode) {
  const ByteString kContents =
      MakeByteString({0xFE, 0xFF, 0x00, 'A', 0x00, 'a', 0x00, 0xE4, 0x20, 0xAC,
                      0xD8, 0x3C, 0xDF, 0xA8});
  AddTextAnnotation(kContents);

  CPDF_AnnotList list(page_);

  ASSERT_EQ(2u, list.Count());
  EXPECT_EQ(kContents, GetRawContents(list.GetAt(1)));

  EXPECT_EQ(WideString::FromUTF8("Aaä€🎨"), GetDecodedContents(list.GetAt(1)));
}

TEST_F(CPDFAnnotListTest, CreatePopupAnnotFromEmptyPdfEncoded) {
  AddTextAnnotation("");

  CPDF_AnnotList list(page_);

  EXPECT_EQ(1u, list.Count());
}

TEST_F(CPDFAnnotListTest, CreatePopupAnnotFromEmptyUnicode) {
  const ByteString kContents = MakeByteString({0xFE, 0xFF});
  AddTextAnnotation(kContents);

  CPDF_AnnotList list(page_);

  EXPECT_EQ(1u, list.Count());
}

TEST_F(CPDFAnnotListTest, CreatePopupAnnotFromEmptyUnicodedWithEscape) {
  const ByteString kContents =
      MakeByteString({0xFE, 0xFF, 0x00, 0x1B, 'j', 'a', 0x00, 0x1B});
  AddTextAnnotation(kContents);

  CPDF_AnnotList list(page_);

  EXPECT_EQ(1u, list.Count());
}
