// Copyright 2016 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 <memory>
#include <vector>

#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/cpdf_name.h"
#include "core/fpdfapi/fpdf_parser/cpdf_string.h"
#include "core/fpdfdoc/cpdf_filespec.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/test_support.h"

namespace {

using ScopedObj = std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>>;
using ScopedDict =
    std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>>;
}

TEST(cpdf_filespec, EncodeDecodeFileName) {
  std::vector<pdfium::NullTermWstrFuncTestData> test_data = {
    // Empty src string.
    {L"", L""},
    // only file name.
    {L"test.pdf", L"test.pdf"},
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    // With drive identifier.
    {L"r:\\pdfdocs\\spec.pdf", L"/r/pdfdocs/spec.pdf"},
    // Relative path.
    {L"My Document\\test.pdf", L"My Document/test.pdf"},
    // Absolute path without drive identifier.
    {L"\\pdfdocs\\spec.pdf", L"//pdfdocs/spec.pdf"},
    // Absolute path with double backslashes.
    {L"\\\\pdfdocs\\spec.pdf", L"/pdfdocs/spec.pdf"},
// Network resource name. It is not supported yet.
// {L"pclib/eng:\\pdfdocs\\spec.pdf", L"/pclib/eng/pdfdocs/spec.pdf"},
#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
    // Absolute path with colon separator.
    {L"Mac HD:PDFDocs:spec.pdf", L"/Mac HD/PDFDocs/spec.pdf"},
    // Relative path with colon separator.
    {L"PDFDocs:spec.pdf", L"PDFDocs/spec.pdf"},
#else
    // Relative path.
    {L"./docs/test.pdf", L"./docs/test.pdf"},
    // Relative path with parent dir.
    {L"../test_docs/test.pdf", L"../test_docs/test.pdf"},
    // Absolute path.
    {L"/usr/local/home/test.pdf", L"/usr/local/home/test.pdf"},
#endif
  };
  for (const auto& data : test_data) {
    CFX_WideString encoded_str = CPDF_FileSpec::EncodeFileName(data.input);
    EXPECT_TRUE(encoded_str == data.expected);
    // DecodeFileName is the reverse procedure of EncodeFileName.
    CFX_WideString decoded_str = CPDF_FileSpec::DecodeFileName(data.expected);
    EXPECT_TRUE(decoded_str == data.input);
  }
}

TEST(cpdf_filespec, GetFileName) {
  {
    // String object.
    pdfium::NullTermWstrFuncTestData test_data = {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
      L"/C/docs/test.pdf",
      L"C:\\docs\\test.pdf"
#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
      L"/Mac HD/docs/test.pdf",
      L"Mac HD:docs:test.pdf"
#else
      L"/docs/test.pdf",
      L"/docs/test.pdf"
#endif
    };
    ScopedObj str_obj(new CPDF_String(test_data.input));
    CPDF_FileSpec file_spec(str_obj.get());
    CFX_WideString file_name;
    EXPECT_TRUE(file_spec.GetFileName(&file_name));
    EXPECT_TRUE(file_name == test_data.expected);
  }
  {
    // Dictionary object.
    pdfium::NullTermWstrFuncTestData test_data[5] = {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
      {L"/C/docs/test.pdf", L"C:\\docs\\test.pdf"},
      {L"/D/docs/test.pdf", L"D:\\docs\\test.pdf"},
      {L"/E/docs/test.pdf", L"E:\\docs\\test.pdf"},
      {L"/F/docs/test.pdf", L"F:\\docs\\test.pdf"},
      {L"/G/docs/test.pdf", L"G:\\docs\\test.pdf"},
#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
      {L"/Mac HD/docs1/test.pdf", L"Mac HD:docs1:test.pdf"},
      {L"/Mac HD/docs2/test.pdf", L"Mac HD:docs2:test.pdf"},
      {L"/Mac HD/docs3/test.pdf", L"Mac HD:docs3:test.pdf"},
      {L"/Mac HD/docs4/test.pdf", L"Mac HD:docs4:test.pdf"},
      {L"/Mac HD/docs5/test.pdf", L"Mac HD:docs5:test.pdf"},
#else
      {L"/docs/a/test.pdf", L"/docs/a/test.pdf"},
      {L"/docs/b/test.pdf", L"/docs/b/test.pdf"},
      {L"/docs/c/test.pdf", L"/docs/c/test.pdf"},
      {L"/docs/d/test.pdf", L"/docs/d/test.pdf"},
      {L"/docs/e/test.pdf", L"/docs/e/test.pdf"},
#endif
    };
    // Keyword fields in reverse order of precedence to retrieve the file name.
    const char* const keywords[5] = {"Unix", "Mac", "DOS", "F", "UF"};
    ScopedDict dict_obj(new CPDF_Dictionary());
    CPDF_FileSpec file_spec(dict_obj.get());
    CFX_WideString file_name;
    for (int i = 0; i < 5; ++i) {
      dict_obj->SetFor(keywords[i], new CPDF_String(test_data[i].input));
      EXPECT_TRUE(file_spec.GetFileName(&file_name));
      EXPECT_TRUE(file_name == test_data[i].expected);
    }

    // With all the former fields and 'FS' field suggests 'URL' type.
    dict_obj->SetStringFor("FS", "URL");
    EXPECT_TRUE(file_spec.GetFileName(&file_name));
    // Url string is not decoded.
    EXPECT_TRUE(file_name == test_data[4].input);
  }
  {
    // Invalid object.
    ScopedObj name_obj(new CPDF_Name("test.pdf"));
    CPDF_FileSpec file_spec(name_obj.get());
    CFX_WideString file_name;
    EXPECT_FALSE(file_spec.GetFileName(&file_name));
  }
}

TEST(cpdf_filespec, SetFileName) {
  pdfium::NullTermWstrFuncTestData test_data = {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    L"C:\\docs\\test.pdf",
    L"/C/docs/test.pdf"
#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
    L"Mac HD:docs:test.pdf",
    L"/Mac HD/docs/test.pdf"
#else
    L"/docs/test.pdf",
    L"/docs/test.pdf"
#endif
  };
  // String object.
  ScopedObj str_obj(new CPDF_String(L"babababa"));
  CPDF_FileSpec file_spec1(str_obj.get());
  file_spec1.SetFileName(test_data.input);
  // Check internal object value.
  CFX_ByteString str = CFX_ByteString::FromUnicode(test_data.expected);
  EXPECT_TRUE(str == str_obj->GetString());
  // Check we can get the file name back.
  CFX_WideString file_name;
  EXPECT_TRUE(file_spec1.GetFileName(&file_name));
  EXPECT_TRUE(file_name == test_data.input);

  // Dictionary object.
  ScopedDict dict_obj(new CPDF_Dictionary());
  CPDF_FileSpec file_spec2(dict_obj.get());
  file_spec2.SetFileName(test_data.input);
  // Check internal object value.
  file_name = dict_obj->GetUnicodeTextFor("F");
  EXPECT_TRUE(file_name == test_data.expected);
  file_name = dict_obj->GetUnicodeTextFor("UF");
  EXPECT_TRUE(file_name == test_data.expected);
  // Check we can get the file name back.
  EXPECT_TRUE(file_spec2.GetFileName(&file_name));
  EXPECT_TRUE(file_name == test_data.input);
}
