// Copyright 2014 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/fde/cfde_txtedtbuf.h"

#include <algorithm>
#include <utility>

#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"

namespace {

const int kDefaultChunkSize = 1024;

}  // namespace

CFDE_TxtEdtBuf::CFDE_TxtEdtBuf() : m_chunkSize(kDefaultChunkSize), m_nTotal(0) {
  m_chunks.push_back(NewChunk());
}

CFDE_TxtEdtBuf::~CFDE_TxtEdtBuf() {}

int32_t CFDE_TxtEdtBuf::GetChunkSize() const {
  return m_chunkSize;
}

int32_t CFDE_TxtEdtBuf::GetTextLength() const {
  return m_nTotal;
}

void CFDE_TxtEdtBuf::SetText(const CFX_WideString& wsText) {
  ASSERT(!wsText.IsEmpty());

  Clear(false);
  int32_t nTextLength = wsText.GetLength();
  int32_t nNeedCount =
      ((nTextLength - 1) / GetChunkSize() + 1) - m_chunks.size();
  int32_t i = 0;
  for (i = 0; i < nNeedCount; i++)
    m_chunks.push_back(NewChunk());

  int32_t nTotalCount = m_chunks.size();
  const wchar_t* lpSrcBuf = wsText.c_str();
  int32_t nLeave = nTextLength;
  int32_t nCopyedLength = GetChunkSize();
  for (i = 0; i < nTotalCount && nLeave > 0; i++) {
    if (nLeave < nCopyedLength) {
      nCopyedLength = nLeave;
    }

    ChunkHeader* chunk = m_chunks[i].get();
    memcpy(chunk->wChars.get(), lpSrcBuf, nCopyedLength * sizeof(wchar_t));
    nLeave -= nCopyedLength;
    lpSrcBuf += nCopyedLength;
    chunk->nUsed = nCopyedLength;
  }
  m_nTotal = nTextLength;
}

CFX_WideString CFDE_TxtEdtBuf::GetText() const {
  return GetRange(0, m_nTotal);
}

wchar_t CFDE_TxtEdtBuf::GetCharByIndex(int32_t nIndex) const {
  ASSERT(nIndex >= 0 && nIndex < GetTextLength());

  ChunkHeader* pChunkHeader = nullptr;
  int32_t nTotal = 0;
  for (const auto& chunk : m_chunks) {
    pChunkHeader = chunk.get();
    nTotal += pChunkHeader->nUsed;
    if (nTotal > nIndex)
      break;
  }
  ASSERT(pChunkHeader);

  wchar_t* buf = pChunkHeader->wChars.get();
  return buf[pChunkHeader->nUsed - (nTotal - nIndex)];
}

CFX_WideString CFDE_TxtEdtBuf::GetRange(int32_t nBegin, int32_t nLength) const {
  if (nLength == 0 || GetTextLength() == 0)
    return CFX_WideString();

  ASSERT(nBegin >= 0 && nLength > 0 && nBegin < GetTextLength() &&
         nBegin + nLength <= GetTextLength());

  int32_t chunkIndex = 0;
  int32_t charIndex = 0;
  std::tie(chunkIndex, charIndex) = Index2CP(nBegin);

  int32_t nLeave = nLength;
  int32_t nCount = m_chunks.size();

  CFX_WideString wsText;
  wchar_t* lpDstBuf = wsText.GetBuffer(nLength);
  int32_t nChunkIndex = chunkIndex;

  ChunkHeader* chunkHeader = m_chunks[nChunkIndex].get();
  int32_t nCopyLength = chunkHeader->nUsed - charIndex;
  wchar_t* lpSrcBuf = chunkHeader->wChars.get() + charIndex;
  while (nLeave > 0) {
    if (nLeave <= nCopyLength) {
      nCopyLength = nLeave;
    }
    memcpy(lpDstBuf, lpSrcBuf, nCopyLength * sizeof(wchar_t));
    nChunkIndex++;
    if (nChunkIndex >= nCount) {
      break;
    }
    chunkHeader = m_chunks[nChunkIndex].get();
    lpSrcBuf = chunkHeader->wChars.get();
    nLeave -= nCopyLength;
    lpDstBuf += nCopyLength;
    nCopyLength = chunkHeader->nUsed;
  }
  wsText.ReleaseBuffer();

  return wsText;
}

void CFDE_TxtEdtBuf::Insert(int32_t nPos,
                            const wchar_t* lpText,
                            int32_t nLength) {
  ASSERT(nPos >= 0 && nPos <= m_nTotal);
  ASSERT(nLength > 0);

  int32_t chunkIndex = 0;
  int32_t charIndex = 0;
  std::tie(chunkIndex, charIndex) = Index2CP(nPos);

  int32_t nLengthTemp = nLength;
  if (charIndex != 0) {
    auto newChunk = NewChunk();

    ChunkHeader* chunk = m_chunks[chunkIndex].get();
    int32_t nCopy = chunk->nUsed - charIndex;

    memcpy(newChunk->wChars.get(), chunk->wChars.get() + charIndex,
           nCopy * sizeof(wchar_t));
    chunk->nUsed -= nCopy;
    chunkIndex++;

    newChunk->nUsed = nCopy;
    m_chunks.insert(m_chunks.begin() + chunkIndex, std::move(newChunk));
    charIndex = 0;
  }

  if (chunkIndex != 0) {
    ChunkHeader* chunk = m_chunks[chunkIndex - 1].get();
    if (chunk->nUsed != GetChunkSize()) {
      chunkIndex--;
      int32_t nFree = GetChunkSize() - chunk->nUsed;
      int32_t nCopy = std::min(nLengthTemp, nFree);
      memcpy(chunk->wChars.get() + chunk->nUsed, lpText,
             nCopy * sizeof(wchar_t));
      lpText += nCopy;
      nLengthTemp -= nCopy;
      chunk->nUsed += nCopy;
      chunkIndex++;
    }
  }

  while (nLengthTemp > 0) {
    auto chunk = NewChunk();

    int32_t nCopy = std::min(nLengthTemp, GetChunkSize());
    memcpy(chunk->wChars.get(), lpText, nCopy * sizeof(wchar_t));
    lpText += nCopy;
    nLengthTemp -= nCopy;
    chunk->nUsed = nCopy;
    m_chunks.insert(m_chunks.begin() + chunkIndex, std::move(chunk));
    chunkIndex++;
  }
  m_nTotal += nLength;
}

void CFDE_TxtEdtBuf::Delete(int32_t nIndex, int32_t nLength) {
  ASSERT(nLength > 0 && nIndex >= 0 && nIndex + nLength <= m_nTotal);

  int32_t endChunkIndex = 0;
  int32_t endCharIndex = 0;
  std::tie(endChunkIndex, endCharIndex) = Index2CP(nIndex + nLength - 1);
  m_nTotal -= nLength;

  ChunkHeader* chunk = m_chunks[endChunkIndex].get();
  int32_t nFirstPart = endCharIndex + 1;
  int32_t nMovePart = chunk->nUsed - nFirstPart;
  if (nMovePart != 0) {
    int32_t nDelete = std::min(nFirstPart, nLength);
    memmove(chunk->wChars.get() + nFirstPart - nDelete,
            chunk->wChars.get() + nFirstPart, nMovePart * sizeof(wchar_t));
    chunk->nUsed -= nDelete;
    nLength -= nDelete;
    endChunkIndex--;
  }

  while (nLength > 0) {
    ChunkHeader* curChunk = m_chunks[endChunkIndex].get();
    int32_t nDeleted = std::min(curChunk->nUsed, nLength);
    curChunk->nUsed -= nDeleted;
    if (curChunk->nUsed == 0)
      m_chunks.erase(m_chunks.begin() + endChunkIndex);

    nLength -= nDeleted;
    endChunkIndex--;
  }
}

void CFDE_TxtEdtBuf::Clear(bool bRelease) {
  if (bRelease) {
    m_chunks.clear();
  } else {
    size_t i = 0;
    while (i < m_chunks.size())
      m_chunks[i++]->nUsed = 0;
  }
  m_nTotal = 0;
}

void CFDE_TxtEdtBuf::SetChunkSizeForTesting(size_t size) {
  ASSERT(size > 0);

  m_chunkSize = size;
  m_chunks.clear();
  m_chunks.push_back(NewChunk());
}

std::tuple<int32_t, int32_t> CFDE_TxtEdtBuf::Index2CP(int32_t nIndex) const {
  ASSERT(nIndex <= GetTextLength());

  if (nIndex == m_nTotal) {
    return std::tuple<int32_t, int32_t>(m_chunks.size() - 1,
                                        m_chunks.back()->nUsed);
  }

  int32_t chunkIndex = 0;
  int32_t nTotal = 0;
  for (auto& chunk : m_chunks) {
    nTotal += chunk->nUsed;
    if (nTotal > nIndex)
      break;
    chunkIndex++;
  }

  int32_t charIndex = m_chunks[chunkIndex]->nUsed - (nTotal - nIndex);
  return std::tuple<int32_t, int32_t>(chunkIndex, charIndex);
}

std::unique_ptr<CFDE_TxtEdtBuf::ChunkHeader> CFDE_TxtEdtBuf::NewChunk() {
  auto chunk = pdfium::MakeUnique<ChunkHeader>();
  chunk->wChars.reset(FX_Alloc(wchar_t, GetChunkSize()));
  chunk->nUsed = 0;
  return chunk;
}

CFDE_TxtEdtBuf::ChunkHeader::ChunkHeader() {}

CFDE_TxtEdtBuf::ChunkHeader::~ChunkHeader() {}

CFDE_TxtEdtBuf::Iterator::Iterator(CFDE_TxtEdtBuf* pBuf, wchar_t wcAlias)
    : m_pBuf(pBuf),
      m_nCurChunk(0),
      m_nCurIndex(0),
      m_nIndex(0),
      m_Alias(wcAlias) {
  ASSERT(m_pBuf);
}

CFDE_TxtEdtBuf::Iterator::~Iterator() {}

bool CFDE_TxtEdtBuf::Iterator::Next(bool bPrev) {
  if (bPrev) {
    if (m_nIndex == 0)
      return false;

    ASSERT(m_nCurChunk < pdfium::CollectionSize<int32_t>(m_pBuf->m_chunks));

    ChunkHeader* chunk = nullptr;
    if (m_nCurIndex > 0) {
      m_nCurIndex--;
    } else {
      while (m_nCurChunk > 0) {
        --m_nCurChunk;
        chunk = m_pBuf->m_chunks[m_nCurChunk].get();
        if (chunk->nUsed > 0) {
          m_nCurIndex = chunk->nUsed - 1;
          break;
        }
      }
    }
    ASSERT(m_nCurChunk >= 0);
    m_nIndex--;
    return true;
  } else {
    if (m_nIndex >= (m_pBuf->m_nTotal - 1))
      return false;

    ASSERT(m_nCurChunk < pdfium::CollectionSize<int32_t>(m_pBuf->m_chunks));
    if (m_pBuf->m_chunks[m_nCurChunk]->nUsed != (m_nCurIndex + 1)) {
      m_nCurIndex++;
    } else {
      int32_t nEnd = m_pBuf->m_chunks.size() - 1;
      while (m_nCurChunk < nEnd) {
        m_nCurChunk++;
        ChunkHeader* chunkTemp = m_pBuf->m_chunks[m_nCurChunk].get();
        if (chunkTemp->nUsed > 0) {
          m_nCurIndex = 0;
          break;
        }
      }
    }
    m_nIndex++;
    return true;
  }
}

void CFDE_TxtEdtBuf::Iterator::SetAt(int32_t nIndex) {
  ASSERT(nIndex >= 0 && nIndex < m_pBuf->m_nTotal);

  std::tie(m_nCurChunk, m_nCurIndex) = m_pBuf->Index2CP(nIndex);
  m_nIndex = nIndex;
}

int32_t CFDE_TxtEdtBuf::Iterator::GetAt() const {
  return m_nIndex;
}

wchar_t CFDE_TxtEdtBuf::Iterator::GetChar() {
  ASSERT(m_nIndex >= 0 && m_nIndex < m_pBuf->m_nTotal);
  if (m_Alias == 0 || m_nIndex == (m_pBuf->m_nTotal - 1)) {
    wchar_t* buf = m_pBuf->m_chunks[m_nCurChunk]->wChars.get();
    return buf[m_nCurIndex];
  }
  return m_Alias;
}

bool CFDE_TxtEdtBuf::Iterator::IsEOF(bool bTail) const {
  return bTail ? m_nIndex == (m_pBuf->GetTextLength() - 2) : m_nIndex == 0;
}

std::unique_ptr<IFX_CharIter> CFDE_TxtEdtBuf::Iterator::Clone() {
  auto pIter = pdfium::MakeUnique<CFDE_TxtEdtBuf::Iterator>(m_pBuf);
  pIter->m_nCurChunk = m_nCurChunk;
  pIter->m_nCurIndex = m_nCurIndex;
  pIter->m_nIndex = m_nIndex;
  pIter->m_Alias = m_Alias;
  return pIter;
}
