// Copyright 2018 The 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.

#include "samples/pdfium_test_dump_helper.h"

#include <limits.h>
#include <string.h>

#include <algorithm>
#include <functional>
#include <iterator>
#include <string>
#include <utility>

#include "public/cpp/fpdf_scopers.h"
#include "public/fpdf_transformpage.h"
#include "testing/fx_string_testhelpers.h"

using GetBoxInfoFunc =
    std::function<bool(FPDF_PAGE, float*, float*, float*, float*)>;

namespace {

std::wstring ConvertToWString(const unsigned short* buf,
                              unsigned long buf_size) {
  std::wstring result;
  result.reserve(buf_size);
  std::copy(buf, buf + buf_size, std::back_inserter(result));
  return result;
}

void DumpBoxInfo(GetBoxInfoFunc func,
                 const char* box_type,
                 FPDF_PAGE page,
                 int page_idx) {
  FS_RECTF rect;
  bool ret = func(page, &rect.left, &rect.bottom, &rect.right, &rect.top);
  if (!ret) {
    printf("Page %d: No %s.\n", page_idx, box_type);
    return;
  }
  printf("Page %d: %s: %0.2f %0.2f %0.2f %0.2f\n", page_idx, box_type,
         rect.left, rect.bottom, rect.right, rect.top);
}

void DumpStructureElementAttributes(FPDF_STRUCTELEMENT_ATTR attr, int indent) {
  static const size_t kBufSize = 1024;
  int count = FPDF_StructElement_Attr_GetCount(attr);
  for (int i = 0; i < count; i++) {
    char name[kBufSize] = {};
    unsigned long len = ULONG_MAX;
    if (!FPDF_StructElement_Attr_GetName(attr, i, name, sizeof(name), &len)) {
      printf("%*s FPDF_StructElement_Attr_GetName failed for %d\n", indent, "",
             i);
      continue;
    }

    FPDF_OBJECT_TYPE type = FPDF_StructElement_Attr_GetType(attr, name);
    if (type == FPDF_OBJECT_BOOLEAN) {
      int value;
      if (!FPDF_StructElement_Attr_GetBooleanValue(attr, name, &value)) {
        printf("%*s %s: Failed FPDF_StructElement_Attr_GetBooleanValue\n",
               indent, "", name);
        continue;
      }
      printf("%*s %s: %d\n", indent, "", name, value);
    } else if (type == FPDF_OBJECT_NUMBER) {
      float value;
      if (!FPDF_StructElement_Attr_GetNumberValue(attr, name, &value)) {
        printf("%*s %s: Failed FPDF_StructElement_Attr_GetNumberValue\n",
               indent, "", name);
        continue;
      }
      printf("%*s %s: %f\n", indent, "", name, value);
    } else if (type == FPDF_OBJECT_STRING || type == FPDF_OBJECT_NAME) {
      unsigned short buffer[kBufSize] = {};
      if (!FPDF_StructElement_Attr_GetStringValue(attr, name, buffer,
                                                  sizeof(buffer), &len)) {
        printf("%*s %s: Failed FPDF_StructElement_Attr_GetStringValue\n",
               indent, "", name);
        continue;
      }
      printf("%*s %s: %ls\n", indent, "", name,
             ConvertToWString(buffer, len).c_str());
    } else if (type == FPDF_OBJECT_UNKNOWN) {
      printf("%*s %s: FPDF_OBJECT_UNKNOWN\n", indent, "", name);
    } else {
      printf("%*s %s: NOT_YET_IMPLEMENTED: %d\n", indent, "", name, type);
    }
  }
}

}  // namespace

void DumpChildStructure(FPDF_STRUCTELEMENT child, int indent) {
  static const size_t kBufSize = 1024;
  unsigned short buf[kBufSize];
  unsigned long len = FPDF_StructElement_GetType(child, buf, kBufSize);
  if (len > 0)
    printf("%*s S: %ls\n", indent * 2, "", ConvertToWString(buf, len).c_str());

  int attr_count = FPDF_StructElement_GetAttributeCount(child);
  for (int i = 0; i < attr_count; i++) {
    FPDF_STRUCTELEMENT_ATTR child_attr =
        FPDF_StructElement_GetAttributeAtIndex(child, i);
    if (!child_attr)
      continue;
    printf("%*s A[%d]:\n", indent * 2, "", i);
    DumpStructureElementAttributes(child_attr, indent * 2 + 2);
  }

  memset(buf, 0, sizeof(buf));
  len = FPDF_StructElement_GetActualText(child, buf, kBufSize);
  if (len > 0) {
    printf("%*s ActualText: %ls\n", indent * 2, "",
           ConvertToWString(buf, len).c_str());
  }

  memset(buf, 0, sizeof(buf));
  len = FPDF_StructElement_GetAltText(child, buf, kBufSize);
  if (len > 0) {
    printf("%*s AltText: %ls\n", indent * 2, "",
           ConvertToWString(buf, len).c_str());
  }

  memset(buf, 0, sizeof(buf));
  len = FPDF_StructElement_GetID(child, buf, kBufSize);
  if (len > 0)
    printf("%*s ID: %ls\n", indent * 2, "", ConvertToWString(buf, len).c_str());

  memset(buf, 0, sizeof(buf));
  len = FPDF_StructElement_GetLang(child, buf, kBufSize);
  if (len > 0) {
    printf("%*s Lang: %ls\n", indent * 2, "",
           ConvertToWString(buf, len).c_str());
  }

  int mcid = FPDF_StructElement_GetMarkedContentID(child);
  if (mcid != -1)
    printf("%*s MCID: %d\n", indent * 2, "", mcid);

  FPDF_STRUCTELEMENT parent = FPDF_StructElement_GetParent(child);
  if (parent) {
    memset(buf, 0, sizeof(buf));
    len = FPDF_StructElement_GetID(parent, buf, kBufSize);
    if (len > 0) {
      printf("%*s Parent ID: %ls\n", indent * 2, "",
             ConvertToWString(buf, len).c_str());
    }
  }

  memset(buf, 0, sizeof(buf));
  len = FPDF_StructElement_GetTitle(child, buf, kBufSize);
  if (len > 0) {
    printf("%*s Title: %ls\n", indent * 2, "",
           ConvertToWString(buf, len).c_str());
  }

  memset(buf, 0, sizeof(buf));
  len = FPDF_StructElement_GetObjType(child, buf, kBufSize);
  if (len > 0) {
    printf("%*s Type: %ls\n", indent * 2, "",
           ConvertToWString(buf, len).c_str());
  }

  for (int i = 0; i < FPDF_StructElement_CountChildren(child); ++i) {
    FPDF_STRUCTELEMENT sub_child = FPDF_StructElement_GetChildAtIndex(child, i);
    // If the child is not an Element then this will return null. This can
    // happen if the element is things like an object reference or a stream.
    if (!sub_child)
      continue;

    DumpChildStructure(sub_child, indent + 1);
  }
}

void DumpPageInfo(FPDF_PAGE page, int page_idx) {
  DumpBoxInfo(&FPDFPage_GetMediaBox, "MediaBox", page, page_idx);
  DumpBoxInfo(&FPDFPage_GetCropBox, "CropBox", page, page_idx);
  DumpBoxInfo(&FPDFPage_GetBleedBox, "BleedBox", page, page_idx);
  DumpBoxInfo(&FPDFPage_GetTrimBox, "TrimBox", page, page_idx);
  DumpBoxInfo(&FPDFPage_GetArtBox, "ArtBox", page, page_idx);
}

void DumpPageStructure(FPDF_PAGE page, int page_idx) {
  ScopedFPDFStructTree tree(FPDF_StructTree_GetForPage(page));
  if (!tree) {
    fprintf(stderr, "Failed to load struct tree for page %d\n", page_idx);
    return;
  }

  printf("Structure Tree for Page %d\n", page_idx);
  for (int i = 0; i < FPDF_StructTree_CountChildren(tree.get()); ++i) {
    FPDF_STRUCTELEMENT child = FPDF_StructTree_GetChildAtIndex(tree.get(), i);
    if (!child) {
      fprintf(stderr, "Failed to load child %d for page %d\n", i, page_idx);
      continue;
    }
    DumpChildStructure(child, 0);
  }
  printf("\n\n");
}

void DumpMetaData(FPDF_DOCUMENT doc) {
  static constexpr const char* kMetaTags[] = {
      "Title",   "Author",   "Subject",      "Keywords",
      "Creator", "Producer", "CreationDate", "ModDate"};
  for (const char* meta_tag : kMetaTags) {
    char meta_buffer[4096];
    unsigned long len =
        FPDF_GetMetaText(doc, meta_tag, meta_buffer, sizeof(meta_buffer));
    if (!len)
      continue;

    auto* meta_string = reinterpret_cast<unsigned short*>(meta_buffer);
    printf("%-12s = %ls (%lu bytes)\n", meta_tag,
           GetPlatformWString(meta_string).c_str(), len);
  }
}
