/*
 * Copyright (C) 2009-2011, Pino Toscano <pino@kde.org>
 * Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
 * Copyright (C) 2018 Albert Astals Cid <aacid@kde.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 */

/**
 \file poppler-embedded-file.h
 */
#include "poppler-embedded-file.h"

#include "poppler-embedded-file-private.h"
#include "poppler-private.h"

#include "Object.h"
#include "Stream.h"
#include "Catalog.h"
#include "FileSpec.h"
#include "DateInfo.h"

using namespace poppler;

embedded_file_private::embedded_file_private(FileSpec *fs)
    : file_spec(fs)
{
}

embedded_file_private::~embedded_file_private()
{
    delete file_spec;
}

embedded_file* embedded_file_private::create(FileSpec *fs)
{
    return new embedded_file(*new embedded_file_private(fs));
}

/**
 \class poppler::embedded_file poppler-embedded-file.h "poppler/cpp/poppler-embedded-file.h"

 Represents a file embedded in a PDF %document.
 */


embedded_file::embedded_file(embedded_file_private &dd)
    : d(&dd)
{
}

/**
 Destroys the embedded file.
 */
embedded_file::~embedded_file()
{
    delete d;
}

/**
 \returns whether the embedded file is valid
 */
bool embedded_file::is_valid() const
{
    return d->file_spec->isOk();
}

/**
 \returns the name of the embedded file
 */
std::string embedded_file::name() const
{
    const GooString *goo = d->file_spec->getFileName();
    return goo ? std::string(goo->c_str()) : std::string();
}

/**
 \returns the description of the embedded file
 */
ustring embedded_file::description() const
{
    const GooString *goo = d->file_spec->getDescription();
    return goo ? detail::unicode_GooString_to_ustring(goo) : ustring();
}

/**
 \note this is not always available in the PDF %document, in that case this
       will return \p -1.

 \returns the size of the embedded file, if known
 */
int embedded_file::size() const
{
    return d->file_spec->getEmbeddedFile()->size();
}

/**
 \returns the time_t representing the modification date of the embedded file,
          if available
 */
time_type embedded_file::modification_date() const
{
    const GooString *goo = d->file_spec->getEmbeddedFile()->modDate();
    return goo ? dateStringToTime(goo) : time_type(-1);
}

/**
 \returns the time_t representing the creation date of the embedded file,
          if available
 */
time_type embedded_file::creation_date() const
{
    const GooString *goo = d->file_spec->getEmbeddedFile()->createDate();
    return goo ? dateStringToTime(goo) : time_type(-1);
}

/**
 \returns the checksum of the embedded file
 */
byte_array embedded_file::checksum() const
{
    const GooString *cs = d->file_spec->getEmbeddedFile()->checksum();
    if (!cs) {
        return byte_array();
    }
    const char *ccs = cs->c_str();
    byte_array data(cs->getLength());
    for (int i = 0; i < cs->getLength(); ++i) {
        data[i] = ccs[i];
    }
    return data;
}

/**
 \returns the MIME type of the embedded file, if available
 */
std::string embedded_file::mime_type() const
{
    const GooString *goo = d->file_spec->getEmbeddedFile()->mimeType();
    return goo ? std::string(goo->c_str()) : std::string();
}

/**
 Reads all the data of the embedded file.

 \returns the data of the embedded file
 */
byte_array embedded_file::data() const
{
    if (!is_valid()) {
        return byte_array();
    }
    Stream *stream = d->file_spec->getEmbeddedFile()->stream();
    if (!stream) {
        return byte_array();
    }

    stream->reset();
    byte_array ret(1024);
    size_t data_len = 0;
    int i;
    while ((i = stream->getChar()) != EOF) {
        if (data_len == ret.size()) {
            ret.resize(ret.size() * 2);
        }
        ret[data_len] = (char)i;
        ++data_len;
    }
    ret.resize(data_len);
    return ret;
}
