// Copyright 2016 The PDFium Authors
// 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 "core/fxge/cfx_folderfontinfo.h"

#include <algorithm>
#include <array>
#include <iterator>
#include <limits>
#include <utility>

#include "build/build_config.h"
#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/containers/contains.h"
#include "core/fxcrt/debug/alias.h"
#include "core/fxcrt/fixed_size_data_vector.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_folder.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/fx_font.h"

namespace {

struct FontSubst {
  const char* m_pName;
  const char* m_pSubstName;
};

constexpr auto kBase14Substs = fxcrt::ToArray<const FontSubst>({
    {"Courier", "Courier New"},
    {"Courier-Bold", "Courier New Bold"},
    {"Courier-BoldOblique", "Courier New Bold Italic"},
    {"Courier-Oblique", "Courier New Italic"},
    {"Helvetica", "Arial"},
    {"Helvetica-Bold", "Arial Bold"},
    {"Helvetica-BoldOblique", "Arial Bold Italic"},
    {"Helvetica-Oblique", "Arial Italic"},
    {"Times-Roman", "Times New Roman"},
    {"Times-Bold", "Times New Roman Bold"},
    {"Times-BoldItalic", "Times New Roman Bold Italic"},
    {"Times-Italic", "Times New Roman Italic"},
});

// Used with std::unique_ptr to automatically call fclose().
struct FxFileCloser {
  inline void operator()(FILE* h) const {
    if (h)
      fclose(h);
  }
};

bool FindFamilyNameMatch(ByteStringView family_name,
                         const ByteString& installed_font_name) {
  std::optional<size_t> result = installed_font_name.Find(family_name, 0);
  if (!result.has_value())
    return false;

  size_t next_index = result.value() + family_name.GetLength();
  // Rule out the case that |family_name| is a substring of
  // |installed_font_name| but their family names are actually different words.
  // For example: "Univers" and "Universal" are not a match because they have
  // different family names, but "Univers" and "Univers Bold" are a match.
  if (installed_font_name.IsValidIndex(next_index) &&
      FXSYS_IsLowerASCII(installed_font_name[next_index])) {
    return false;
  }

  return true;
}

ByteString ReadStringFromFile(FILE* pFile, uint32_t size) {
  ByteString result;
  {
    // Span's lifetime must end before ReleaseBuffer() below.
    pdfium::span<char> buffer = result.GetBuffer(size);

    // SAFETY: GetBuffer(size) ensures size bytes available.
    if (!UNSAFE_BUFFERS(fread(buffer.data(), size, 1, pFile))) {
      return ByteString();
    }
  }
  result.ReleaseBuffer(size);
  return result;
}

ByteString LoadTableFromTT(FILE* pFile,
                           const uint8_t* pTables,
                           uint32_t nTables,
                           uint32_t tag,
                           FX_FILESIZE fileSize) {
  UNSAFE_TODO({
    for (uint32_t i = 0; i < nTables; i++) {
      // TODO(tsepez): use actual span.
      auto p = pdfium::make_span(pTables + i * 16, 16u);
      if (fxcrt::GetUInt32MSBFirst(p) == tag) {
        uint32_t offset = fxcrt::GetUInt32MSBFirst(p.subspan(8));
        uint32_t size = fxcrt::GetUInt32MSBFirst(p.subspan(12));
        if (offset > std::numeric_limits<uint32_t>::max() - size ||
            static_cast<FX_FILESIZE>(offset + size) > fileSize ||
            fseek(pFile, offset, SEEK_SET) < 0) {
          return ByteString();
        }
        return ReadStringFromFile(pFile, size);
      }
    }
  });
  return ByteString();
}

uint32_t GetCharset(FX_Charset charset) {
  switch (charset) {
    case FX_Charset::kShiftJIS:
      return CHARSET_FLAG_SHIFTJIS;
    case FX_Charset::kChineseSimplified:
      return CHARSET_FLAG_GB;
    case FX_Charset::kChineseTraditional:
      return CHARSET_FLAG_BIG5;
    case FX_Charset::kHangul:
      return CHARSET_FLAG_KOREAN;
    case FX_Charset::kSymbol:
      return CHARSET_FLAG_SYMBOL;
    case FX_Charset::kANSI:
      return CHARSET_FLAG_ANSI;
    default:
      break;
  }
  return 0;
}

}  // namespace

CFX_FolderFontInfo::CFX_FolderFontInfo() = default;

CFX_FolderFontInfo::~CFX_FolderFontInfo() = default;

void CFX_FolderFontInfo::AddPath(const ByteString& path) {
  m_PathList.push_back(path);
}

void CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) {
  m_pMapper = pMapper;
  for (const auto& path : m_PathList) {
    ScanPath(path);
  }
}

void CFX_FolderFontInfo::ScanPath(const ByteString& path) {
  std::unique_ptr<FX_Folder> handle = FX_Folder::OpenFolder(path);
  if (!handle)
    return;

  ByteString filename;
  bool bFolder;
  while (handle->GetNextFile(&filename, &bFolder)) {
    if (bFolder) {
      if (filename == "." || filename == "..")
        continue;
    } else {
      ByteString ext = filename.Last(4);
      ext.MakeLower();
      if (ext != ".ttf" && ext != ".ttc" && ext != ".otf")
        continue;
    }

    ByteString fullpath = path;
#if BUILDFLAG(IS_WIN)
    fullpath += "\\";
#else
    fullpath += "/";
#endif

    fullpath += filename;
    bFolder ? ScanPath(fullpath) : ScanFile(fullpath);
  }
}

void CFX_FolderFontInfo::ScanFile(const ByteString& path) {
  std::unique_ptr<FILE, FxFileCloser> pFile(fopen(path.c_str(), "rb"));
  if (!pFile)
    return;

  fseek(pFile.get(), 0, SEEK_END);

  FX_FILESIZE filesize = ftell(pFile.get());
  uint8_t buffer[16];
  fseek(pFile.get(), 0, SEEK_SET);

  // SAFETY: 12 byte read fits into 16 byte buffer,
  size_t items_read =
      UNSAFE_BUFFERS(fread(buffer, /*size=*/12, /*nmemb=*/1, pFile.get()));
  if (items_read != 1) {
    return;
  }
  uint32_t magic =
      fxcrt::GetUInt32MSBFirst(pdfium::make_span(buffer).first<4u>());
  if (magic != kTableTTCF) {
    ReportFace(path, pFile.get(), filesize, 0);
    return;
  }

  uint32_t nFaces =
      fxcrt::GetUInt32MSBFirst(pdfium::make_span(buffer).subspan<8u>());
  FX_SAFE_SIZE_T safe_face_bytes = nFaces;
  safe_face_bytes *= 4;
  if (!safe_face_bytes.IsValid())
    return;

  auto offsets =
      FixedSizeDataVector<uint8_t>::Uninit(safe_face_bytes.ValueOrDie());
  pdfium::span<uint8_t> offsets_span = offsets.span();
  items_read = UNSAFE_TODO(fread(offsets_span.data(), /*size=*/1,
                                 /*nmemb=*/offsets_span.size(), pFile.get()));
  if (items_read != offsets_span.size()) {
    return;
  }

  for (uint32_t i = 0; i < nFaces; i++) {
    ReportFace(path, pFile.get(), filesize,
               fxcrt::GetUInt32MSBFirst(offsets_span.subspan(i * 4)));
  }
}

void CFX_FolderFontInfo::ReportFace(const ByteString& path,
                                    FILE* pFile,
                                    FX_FILESIZE filesize,
                                    uint32_t offset) {
  char buffer[16];
  if (fseek(pFile, offset, SEEK_SET) < 0) {
    return;
  }
  // SAFTEY: 12 byt read fits in 16 byte buffer.
  if (UNSAFE_BUFFERS(!fread(buffer, 12, 1, pFile))) {
    return;
  }

  uint32_t nTables =
      fxcrt::GetUInt16MSBFirst(pdfium::as_byte_span(buffer).subspan<4, 2>());
  ByteString tables = ReadStringFromFile(pFile, nTables * 16);
  if (tables.IsEmpty())
    return;

  static constexpr uint32_t kNameTag =
      CFX_FontMapper::MakeTag('n', 'a', 'm', 'e');
  ByteString names = LoadTableFromTT(pFile, tables.unsigned_str(), nTables,
                                     kNameTag, filesize);
  if (names.IsEmpty())
    return;

  ByteString facename = GetNameFromTT(names.unsigned_span(), 1);
  if (facename.IsEmpty())
    return;

  ByteString style = GetNameFromTT(names.unsigned_span(), 2);
  if (style != "Regular")
    facename += " " + style;

  if (pdfium::Contains(m_FontList, facename))
    return;

  auto pInfo =
      std::make_unique<FontFaceInfo>(path, facename, tables, offset, filesize);
  static constexpr uint32_t kOs2Tag =
      CFX_FontMapper::MakeTag('O', 'S', '/', '2');
  ByteString os2 =
      LoadTableFromTT(pFile, tables.unsigned_str(), nTables, kOs2Tag, filesize);
  if (os2.GetLength() >= 86) {
    pdfium::span<const uint8_t> p = os2.unsigned_span().subspan(78);
    uint32_t codepages = fxcrt::GetUInt32MSBFirst(p);
    if (codepages & (1U << 17)) {
      m_pMapper->AddInstalledFont(facename, FX_Charset::kShiftJIS);
      pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS;
    }
    if (codepages & (1U << 18)) {
      m_pMapper->AddInstalledFont(facename, FX_Charset::kChineseSimplified);
      pInfo->m_Charsets |= CHARSET_FLAG_GB;
    }
    if (codepages & (1U << 20)) {
      m_pMapper->AddInstalledFont(facename, FX_Charset::kChineseTraditional);
      pInfo->m_Charsets |= CHARSET_FLAG_BIG5;
    }
    if ((codepages & (1U << 19)) || (codepages & (1U << 21))) {
      m_pMapper->AddInstalledFont(facename, FX_Charset::kHangul);
      pInfo->m_Charsets |= CHARSET_FLAG_KOREAN;
    }
    if (codepages & (1U << 31)) {
      m_pMapper->AddInstalledFont(facename, FX_Charset::kSymbol);
      pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL;
    }
  }
  m_pMapper->AddInstalledFont(facename, FX_Charset::kANSI);
  pInfo->m_Charsets |= CHARSET_FLAG_ANSI;
  pInfo->m_Styles = 0;
  if (style.Contains("Bold")) {
    pInfo->m_Styles |= pdfium::kFontStyleForceBold;
  }
  if (style.Contains("Italic") || style.Contains("Oblique")) {
    pInfo->m_Styles |= pdfium::kFontStyleItalic;
  }
  if (facename.Contains("Serif")) {
    pInfo->m_Styles |= pdfium::kFontStyleSerif;
  }

  m_FontList[facename] = std::move(pInfo);
}

void* CFX_FolderFontInfo::GetSubstFont(const ByteString& face) {
  for (size_t iBaseFont = 0; iBaseFont < std::size(kBase14Substs);
       iBaseFont++) {
    if (face == kBase14Substs[iBaseFont].m_pName) {
      return GetFont(kBase14Substs[iBaseFont].m_pSubstName);
    }
  }
  return nullptr;
}

void* CFX_FolderFontInfo::FindFont(int weight,
                                   bool bItalic,
                                   FX_Charset charset,
                                   int pitch_family,
                                   const ByteString& family,
                                   bool bMatchName) {
  FontFaceInfo* pFind = nullptr;
  uint32_t charset_flag = GetCharset(charset);

  int32_t iBestSimilar = 0;
  if (bMatchName) {
    // Try a direct lookup for either a perfect score or to determine a
    // baseline similarity score.
    auto direct_it = m_FontList.find(family);
    if (direct_it != m_FontList.end()) {
      FontFaceInfo* pFont = direct_it->second.get();
      if (pFont->IsEligibleForFindFont(charset_flag, charset)) {
        iBestSimilar =
            pFont->SimilarityScore(weight, bItalic, pitch_family, bMatchName);
        if (iBestSimilar == FontFaceInfo::kSimilarityScoreMax) {
          return pFont;
        }
        pFind = pFont;
      }
    }
  }
  // Try and find a better match. Since FindFamilyNameMatch() is expensive,
  // avoid calling it unless there might be a better match.
  ByteStringView bsFamily = family.AsStringView();
  for (const auto& it : m_FontList) {
    const ByteString& bsName = it.first;
    FontFaceInfo* pFont = it.second.get();
    if (!pFont->IsEligibleForFindFont(charset_flag, charset)) {
      continue;
    }
    int32_t iSimilarValue = pFont->SimilarityScore(
        weight, bItalic, pitch_family,
        bMatchName && bsFamily.GetLength() == bsName.GetLength());
    if (iSimilarValue > iBestSimilar) {
      if (bMatchName && !FindFamilyNameMatch(bsFamily, bsName)) {
        continue;
      }
      iBestSimilar = iSimilarValue;
      pFind = pFont;
    }
  }

  if (pFind) {
    return pFind;
  }

  if (charset == FX_Charset::kANSI && FontFamilyIsFixedPitch(pitch_family)) {
    auto* courier_new = GetFont("Courier New");
    if (courier_new)
      return courier_new;
  }

  return nullptr;
}

void* CFX_FolderFontInfo::MapFont(int weight,
                                  bool bItalic,
                                  FX_Charset charset,
                                  int pitch_family,
                                  const ByteString& face) {
  return nullptr;
}

void* CFX_FolderFontInfo::GetFont(const ByteString& face) {
  auto it = m_FontList.find(face);
  return it != m_FontList.end() ? it->second.get() : nullptr;
}

size_t CFX_FolderFontInfo::GetFontData(void* hFont,
                                       uint32_t table,
                                       pdfium::span<uint8_t> buffer) {
  if (!hFont)
    return 0;

  const FontFaceInfo* pFont = static_cast<FontFaceInfo*>(hFont);
  uint32_t datasize = 0;
  uint32_t offset = 0;
  if (table == 0) {
    datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize;
  } else if (table == kTableTTCF) {
    datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0;
  } else {
    size_t nTables = pFont->m_FontTables.GetLength() / 16;
    for (size_t i = 0; i < nTables; i++) {
      // TODO(tsepez): iterate over span.
      pdfium::span<const uint8_t> p =
          pFont->m_FontTables.unsigned_span().subspan(i * 16);
      if (fxcrt::GetUInt32MSBFirst(p) == table) {
        offset = fxcrt::GetUInt32MSBFirst(p.subspan(8));
        datasize = fxcrt::GetUInt32MSBFirst(p.subspan(12));
      }
    }
  }

  if (!datasize || buffer.size() < datasize)
    return datasize;

  std::unique_ptr<FILE, FxFileCloser> pFile(
      fopen(pFont->m_FilePath.c_str(), "rb"));
  if (!pFile)
    return 0;

  if (fseek(pFile.get(), offset, SEEK_SET) < 0) {
    return 0;
  }

  // TODO(crbug.com/376633555): Remove debugging data after fixing the bug.
  pdfium::Alias(&datasize);
  char buf[256] = {};
  pdfium::Alias(&buf);
  ByteStringView font_path = pFont->m_FilePath.AsStringView();
  size_t path_char_count = std::min(font_path.GetLength(), std::size(buf));
  fxcrt::spancpy(pdfium::span(buf), font_path.Last(path_char_count).span());

  if (UNSAFE_TODO(fread(buffer.data(), datasize, 1, pFile.get())) != 1) {
    return 0;
  }
  return datasize;
}

void CFX_FolderFontInfo::DeleteFont(void* hFont) {}

bool CFX_FolderFontInfo::GetFaceName(void* hFont, ByteString* name) {
  if (!hFont)
    return false;
  *name = static_cast<FontFaceInfo*>(hFont)->m_FaceName;
  return true;
}

bool CFX_FolderFontInfo::GetFontCharset(void* hFont, FX_Charset* charset) {
  return false;
}

CFX_FolderFontInfo::FontFaceInfo::FontFaceInfo(ByteString filePath,
                                               ByteString faceName,
                                               ByteString fontTables,
                                               uint32_t fontOffset,
                                               uint32_t fileSize)
    : m_FilePath(filePath),
      m_FaceName(faceName),
      m_FontTables(fontTables),
      m_FontOffset(fontOffset),
      m_FileSize(fileSize) {}

bool CFX_FolderFontInfo::FontFaceInfo::IsEligibleForFindFont(
    uint32_t flag,
    FX_Charset charset) const {
  return (m_Charsets & flag) || charset == FX_Charset::kDefault;
}

int32_t CFX_FolderFontInfo::FontFaceInfo::SimilarityScore(
    int weight,
    bool italic,
    int pitch_family,
    bool exact_match_bonus) const {
  int32_t score = 0;
  if (FontStyleIsForceBold(m_Styles) == (weight > 400)) {
    score += 16;
  }
  if (FontStyleIsItalic(m_Styles) == italic) {
    score += 16;
  }
  if (FontStyleIsSerif(m_Styles) == FontFamilyIsRoman(pitch_family)) {
    score += 16;
  }
  if (FontStyleIsScript(m_Styles) == FontFamilyIsScript(pitch_family)) {
    score += 8;
  }
  if (FontStyleIsFixedPitch(m_Styles) == FontFamilyIsFixedPitch(pitch_family)) {
    score += 8;
  }
  if (exact_match_bonus) {
    score += 4;
  }
  DCHECK_LE(score, kSimilarityScoreMax);
  return score;
}
