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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fgas/layout/cfx_rtfbreak.h"

#include <memory>
#include <utility>

#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_gemodule.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/xfa_test_environment.h"
#include "xfa/fgas/font/cfgas_fontmgr.h"
#include "xfa/fgas/font/cfgas_gefont.h"
#include "xfa/fgas/layout/cfx_char.h"

class CFX_RTFBreakTest : public testing::Test {
 public:
  void SetUp() override {
    font_ = CFGAS_GEFont::LoadFont(L"Arial Black", 0, 0,
                                   XFATestEnvironment::GetGlobalFontManager());
    ASSERT_TRUE(font_);
  }

  std::unique_ptr<CFX_RTFBreak> CreateBreak(uint32_t layout_styles) {
    auto rtf_break = std::make_unique<CFX_RTFBreak>(layout_styles);
    rtf_break->SetFont(font_);
    return rtf_break;
  }

 private:
  RetainPtr<CFGAS_GEFont> font_;
};

// As soon as you get one of the control characters the break is complete
// and must be consumed before you get any more characters ....

TEST_F(CFX_RTFBreakTest, AddChars) {
  auto rtf_break = CreateBreak(FX_LAYOUTSTYLE_ExpandTab);

  WideString str(L"Input String.");
  for (wchar_t ch : str)
    EXPECT_EQ(CFX_BreakType::kNone, rtf_break->AppendChar(ch));

  EXPECT_EQ(CFX_BreakType::kParagraph, rtf_break->AppendChar(L'\n'));
  ASSERT_EQ(1, rtf_break->CountBreakPieces());
  EXPECT_EQ(str + L"\n", rtf_break->GetBreakPieceUnstable(0)->GetString());

  rtf_break->ClearBreakPieces();
  rtf_break->Reset();
  EXPECT_EQ(0, rtf_break->GetCurrentLineForTesting()->GetLineEnd());

  str = L"Second str.";
  for (wchar_t ch : str)
    EXPECT_EQ(CFX_BreakType::kNone, rtf_break->AppendChar(ch));

  // Force the end of the break at the end of the string.
  rtf_break->EndBreak(CFX_BreakType::kParagraph);
  ASSERT_EQ(1, rtf_break->CountBreakPieces());
  EXPECT_EQ(str, rtf_break->GetBreakPieceUnstable(0)->GetString());
}

TEST_F(CFX_RTFBreakTest, ControlCharacters) {
  auto rtf_break = CreateBreak(FX_LAYOUTSTYLE_ExpandTab);
  EXPECT_EQ(CFX_BreakType::kLine, rtf_break->AppendChar(L'\v'));
  EXPECT_EQ(CFX_BreakType::kPage, rtf_break->AppendChar(L'\f'));
  const wchar_t kUnicodeParagraphSeparator = 0x2029;
  EXPECT_EQ(CFX_BreakType::kParagraph,
            rtf_break->AppendChar(kUnicodeParagraphSeparator));
  EXPECT_EQ(CFX_BreakType::kParagraph, rtf_break->AppendChar(L'\n'));

  ASSERT_EQ(1, rtf_break->CountBreakPieces());
  EXPECT_EQ(L"\v", rtf_break->GetBreakPieceUnstable(0)->GetString());
}

TEST_F(CFX_RTFBreakTest, BidiLine) {
  auto rtf_break = CreateBreak(FX_LAYOUTSTYLE_ExpandTab);
  rtf_break->SetLineBreakTolerance(1);
  rtf_break->SetFontSize(12);

  WideString input = WideString::FromUTF8(ByteStringView("\xa\x0\xa\xa", 4));
  for (wchar_t ch : input)
    rtf_break->AppendChar(ch);

  std::vector<CFX_Char> chars =
      rtf_break->GetCurrentLineForTesting()->m_LineChars;
  CFX_Char::BidiLine(&chars, chars.size());
  EXPECT_EQ(3u, chars.size());
}
