// 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/fpdfdoc/cpdf_filespec.h"

#include <array>
#include <iterator>
#include <utility>

#include "build/build_config.h"
#include "constants/stream_dict_common.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_system.h"

namespace {

#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
WideString ChangeSlashToPlatform(WideStringView str) {
  WideString result;
  for (auto wch : str) {
    if (wch == '/') {
#if BUILDFLAG(IS_APPLE)
      result += L':';
#else
      result += L'\\';
#endif
    } else {
      result += wch;
    }
  }
  return result;
}

WideString ChangeSlashToPDF(WideStringView str) {
  WideString result;
  for (auto wch : str) {
    if (wch == '\\' || wch == ':') {
      result += L'/';
    } else {
      result += wch;
    }
  }
  return result;
}
#endif  // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)

}  // namespace

CPDF_FileSpec::CPDF_FileSpec(RetainPtr<const CPDF_Object> pObj)
    : obj_(std::move(pObj)) {
  DCHECK(obj_);
}

CPDF_FileSpec::~CPDF_FileSpec() = default;

WideString CPDF_FileSpec::DecodeFileName(const WideString& filepath) {
  if (filepath.IsEmpty()) {
    return WideString();
  }
#if BUILDFLAG(IS_APPLE)
  WideStringView view = filepath.AsStringView();
  if (view.First(sizeof("/Mac") - 1) == WideStringView(L"/Mac")) {
    return ChangeSlashToPlatform(view.Substr(1));
  }
  return ChangeSlashToPlatform(view);
#elif BUILDFLAG(IS_WIN)
  WideStringView view = filepath.AsStringView();
  if (view[0] != L'/') {
    return ChangeSlashToPlatform(view);
  }
  if (view[1] == L'/') {
    return ChangeSlashToPlatform(view.Substr(1));
  }
  if (view[2] == L'/') {
    WideString result;
    result += view[1];
    result += L':';
    result += ChangeSlashToPlatform(view.Substr(2));
    return result;
  }
  WideString result;
  result += L'\\';
  result += ChangeSlashToPlatform(view);
  return result;
#else
  return filepath;
#endif
}

WideString CPDF_FileSpec::GetFileName() const {
  WideString csFileName;
  if (const CPDF_Dictionary* dict = obj_->AsDictionary()) {
    RetainPtr<const CPDF_String> pUF = ToString(dict->GetDirectObjectFor("UF"));
    if (pUF) {
      csFileName = pUF->GetUnicodeText();
    }
    if (csFileName.IsEmpty()) {
      RetainPtr<const CPDF_String> pK =
          ToString(dict->GetDirectObjectFor(pdfium::stream::kF));
      if (pK) {
        csFileName = WideString::FromDefANSI(pK->GetString().AsStringView());
      }
    }
    if (dict->GetByteStringFor("FS") == "URL") {
      return csFileName;
    }

    if (csFileName.IsEmpty()) {
      for (const auto* key : {"DOS", "Mac", "Unix"}) {
        RetainPtr<const CPDF_String> pValue =
            ToString(dict->GetDirectObjectFor(key));
        if (pValue) {
          csFileName =
              WideString::FromDefANSI(pValue->GetString().AsStringView());
          break;
        }
      }
    }
  } else if (const CPDF_String* pString = obj_->AsString()) {
    csFileName = WideString::FromDefANSI(pString->GetString().AsStringView());
  }
  return DecodeFileName(csFileName);
}

RetainPtr<const CPDF_Stream> CPDF_FileSpec::GetFileStream() const {
  const CPDF_Dictionary* dict = obj_->AsDictionary();
  if (!dict) {
    return nullptr;
  }

  // Get the embedded files dictionary.
  RetainPtr<const CPDF_Dictionary> pFiles = dict->GetDictFor("EF");
  if (!pFiles) {
    return nullptr;
  }

  // List of keys to check for the file specification string.
  // Follows the same precedence order as GetFileName().
  static constexpr std::array<const char*, 5> kKeys = {
      {"UF", "F", "DOS", "Mac", "Unix"}};
  size_t end = dict->GetByteStringFor("FS") == "URL" ? 2 : std::size(kKeys);
  for (size_t i = 0; i < end; ++i) {
    ByteStringView key = kKeys[i];
    if (!dict->GetUnicodeTextFor(key).IsEmpty()) {
      RetainPtr<const CPDF_Stream> pStream = pFiles->GetStreamFor(key);
      if (pStream) {
        return pStream;
      }
    }
  }
  return nullptr;
}

RetainPtr<const CPDF_Dictionary> CPDF_FileSpec::GetParamsDict() const {
  RetainPtr<const CPDF_Stream> pStream = GetFileStream();
  return pStream ? pStream->GetDict()->GetDictFor("Params") : nullptr;
}

RetainPtr<CPDF_Dictionary> CPDF_FileSpec::GetMutableParamsDict() {
  return pdfium::WrapRetain(
      const_cast<CPDF_Dictionary*>(GetParamsDict().Get()));
}

WideString CPDF_FileSpec::EncodeFileName(const WideString& filepath) {
  if (filepath.IsEmpty()) {
    return WideString();
  }
#if BUILDFLAG(IS_WIN)
  WideStringView view = filepath.AsStringView();
  if (view[1] == L':') {
    WideString result(L'/');
    result += view[0];
    if (view[2] != L'\\') {
      result += L'/';
    }
    result += ChangeSlashToPDF(view.Substr(2));
    return result;
  }
  if (view[0] == L'\\' && view[1] == L'\\') {
    return ChangeSlashToPDF(view.Substr(1));
  }
  if (view[0] == L'\\') {
    return L'/' + ChangeSlashToPDF(view);
  }
  return ChangeSlashToPDF(view);
#elif BUILDFLAG(IS_APPLE)
  WideStringView view = filepath.AsStringView();
  if (view.First(sizeof("Mac") - 1).EqualsASCII("Mac")) {
    return L'/' + ChangeSlashToPDF(view);
  }
  return ChangeSlashToPDF(view);
#else
  return filepath;
#endif
}
