//========================================================================
//
// FileSpec.cc
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2008-2009 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
// Copyright (C) 2012, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2012 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2019 Christian Persch <chpe@src.gnome.org>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

//========================================================================
//
// Most of the code from Link.cc and PSOutputDev.cc
//
// Copyright 1996-2003 Glyph & Cog, LLC 
//
//========================================================================

#include <config.h>

#include "FileSpec.h"
#include "XRef.h"
#include "goo/gfile.h"

EmbFile::EmbFile(Object &&efStream)
{
  m_size = -1;
  m_createDate = nullptr;
  m_modDate = nullptr;
  m_checksum = nullptr;
  m_mimetype = nullptr;

  m_objStr = std::move(efStream);

  if (m_objStr.isStream()) {
    // dataDict corresponds to Table 3.41 in the PDF1.6 spec.
    Dict *dataDict = m_objStr.streamGetDict();

    // subtype is normally the mimetype
    Object subtypeName = dataDict->lookup("Subtype");
    if (subtypeName.isName()) {
      m_mimetype = new GooString(subtypeName.getName());
    }

    // paramDict corresponds to Table 3.42 in the PDF1.6 spec
    Object paramDict = dataDict->lookup("Params");
    if (paramDict.isDict()) {
      Object paramObj = paramDict.dictLookup("ModDate");
      if (paramObj.isString())
        m_modDate = new GooString(paramObj.getString());

      paramObj = paramDict.dictLookup("CreationDate");
      if (paramObj.isString())
        m_createDate = new GooString(paramObj.getString());

      paramObj = paramDict.dictLookup("Size");
      if (paramObj.isInt())
        m_size = paramObj.getInt();

      paramObj = paramDict.dictLookup("CheckSum");
      if (paramObj.isString())
        m_checksum = new GooString(paramObj.getString());
    }
  }
}

EmbFile::~EmbFile()
{
  delete m_createDate;
  delete m_modDate;
  delete m_checksum;
  delete m_mimetype;
}

bool EmbFile::save(const char *path) {
  FILE *f;
  bool ret;

  if (!(f = openFile(path, "wb"))) {
    return false;
  }
  ret = save2(f);
  fclose(f);
  return ret;
}

bool EmbFile::save2(FILE *f) {
  int c;

  if (unlikely(!m_objStr.isStream()))
    return false;

  m_objStr.streamReset();
  while ((c = m_objStr.streamGetChar()) != EOF) {
    fputc(c, f);
  }
  return true;
}

FileSpec::FileSpec(const Object *fileSpecA)
{
  ok = true;
  fileName = nullptr;
  platformFileName = nullptr;
  embFile = nullptr;
  desc = nullptr;
  fileSpec = fileSpecA->copy();

  Object obj1 = getFileSpecName(fileSpecA);
  if (!obj1.isString()) {
    ok = false;
    error(errSyntaxError, -1, "Invalid FileSpec");
    return;
  }

  fileName = obj1.getString()->copy();

  if (fileSpec.isDict()) {
    obj1 = fileSpec.dictLookup("EF");
    if (obj1.isDict()) {
      fileStream = obj1.dictLookupNF("F").copy();
      if (!fileStream.isRef()) {
        ok = false;
        fileStream.setToNull();
        error(errSyntaxError, -1, "Invalid FileSpec: Embedded file stream is not an indirect reference");
        return;
      }
    }

    obj1 = fileSpec.dictLookup("Desc");
    if (obj1.isString()) {
      desc = obj1.getString()->copy();
    }
  }
}

FileSpec::~FileSpec()
{
  delete fileName;
  delete platformFileName;
  delete embFile;
  delete desc;
}

EmbFile *FileSpec::getEmbeddedFile()
{
  if(!ok)
    return nullptr;

  if (embFile)
    return embFile;

  XRef *xref = fileSpec.getDict()->getXRef();
  embFile = new EmbFile(fileStream.fetch(xref));

  return embFile;
}

Object FileSpec::newFileSpecObject(XRef *xref, GooFile *file, const std::string &fileName)
{
  Object paramsDict = Object(new Dict(xref));
  paramsDict.dictSet("Size", Object(file->size()));

  // No Subtype in the embedded file stream dictionary for now
  Object streamDict = Object(new Dict(xref));
  streamDict.dictSet("Length", Object(file->size()));
  streamDict.dictSet("Params", std::move(paramsDict));

  FileStream *fStream = new FileStream(file, 0, false, file->size(), std::move(streamDict));
  fStream->setNeedsEncryptionOnSave(true);
  Stream *stream = fStream;
  Object streamObj = Object(stream);
  const Ref streamRef = xref->addIndirectObject(&streamObj);

  Dict *efDict = new Dict(xref);
  efDict->set("F", Object(streamRef));

  Dict *fsDict = new Dict(xref);
  fsDict->set("Type", Object(objName, "Filespec"));
  fsDict->set("UF", Object(new GooString(fileName)));
  fsDict->set("EF", Object(efDict));

  return Object(fsDict);
}

GooString *FileSpec::getFileNameForPlatform()
{
  if (platformFileName)
    return platformFileName;

  Object obj1 = getFileSpecNameForPlatform(&fileSpec);
  if (obj1.isString())
    platformFileName = obj1.getString()->copy();

  return platformFileName;
}

Object getFileSpecName (const Object *fileSpec)
{
  if (fileSpec->isString()) {
    return fileSpec->copy();
  }
  
  if (fileSpec->isDict()) {
    Object fileName = fileSpec->dictLookup("UF");
    if (fileName.isString()) {
      return fileName;
    }
    fileName = fileSpec->dictLookup("F");
    if (fileName.isString()) {
      return fileName;
    }
    fileName = fileSpec->dictLookup("DOS");
    if (fileName.isString()) {
      return fileName;
    }
    fileName = fileSpec->dictLookup("Mac");
    if (fileName.isString()) {
      return fileName;
    }
    fileName = fileSpec->dictLookup("Unix");
    if (fileName.isString()) {
      return fileName;
    }
  }
  return Object();
}

Object getFileSpecNameForPlatform (const Object *fileSpec)
{
  if (fileSpec->isString()) {
    return fileSpec->copy();
  }

  Object fileName;
  if (fileSpec->isDict()) {
    fileName = fileSpec->dictLookup("UF");
    if (!fileName.isString ()) {
      fileName = fileSpec->dictLookup("F");
      if (!fileName.isString ()) {
#ifdef _WIN32
	const char *platform = "DOS";
#else
	const char *platform = "Unix";
#endif
        fileName = fileSpec->dictLookup(platform);
	if (!fileName.isString ()) {
	  error(errSyntaxError, -1, "Illegal file spec");
	  return Object();
	}
      }
    }
  } else {
    error(errSyntaxError, -1, "Illegal file spec");
    return Object();
  }

  // system-dependent path manipulation
#ifdef _WIN32
  int i, j;
  GooString *name = fileName.getString()->copy();
  // "//...."             --> "\...."
  // "/x/...."            --> "x:\...."
  // "/server/share/...." --> "\\server\share\...."
  // convert escaped slashes to slashes and unescaped slashes to backslashes
  i = 0;
  if (name->getChar(0) == '/') {
    if (name->getLength() >= 2 && name->getChar(1) == '/') {
      name->del(0);
      i = 0;
    } else if (name->getLength() >= 2 &&
	       ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') ||
		(name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) &&
	       (name->getLength() == 2 || name->getChar(2) == '/')) {
      name->setChar(0, name->getChar(1));
      name->setChar(1, ':');
      i = 2;
    } else {
      for (j = 2; j < name->getLength(); ++j) {
        if (name->getChar(j-1) != '\\' &&
	    name->getChar(j) == '/') {
	  break;
	}
      }
      if (j < name->getLength()) {
        name->setChar(0, '\\');
	name->insert(0, '\\');
	i = 2;
      }
    }
  }
  for (; i < name->getLength(); ++i) {
    if (name->getChar(i) == '/') {
      name->setChar(i, '\\');
    } else if (name->getChar(i) == '\\' &&
	       i+1 < name->getLength() &&
	       name->getChar(i+1) == '/') {
      name->del(i);
    }
  }
  fileName = Object(name);
#endif /* _WIN32 */

  return fileName;
}
