/*
 * Copyright (C) 2014-2026 CZ.NIC
 *
 * 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#include <QFileInfo>
#include <QMimeDatabase>

#include "src/datovka_shared/compat/compiler.h" /* macroStdMove */
#include "src/datovka_shared/io/mime.h"
#include "src/datovka_shared/isds/message_attachment.h"
#include "src/datovka_shared/log/log.h"

/*!
 * @brief Adjust MIME type name if such is insufficiently detected.
 *
 * @param[in,out] mimeName Mime type name to be altered.
 * @param[in] suffix Lower-case suffix used to determine the adequate mime type.
 */
static
void adjustMimeName(QString &mimeName, const QString &suffix)
{
	if (Q_UNLIKELY(!Isds::Attachment::allowedFileSuffixes().contains(suffix))) {
		/* We have no such suffix listed. Use detected MIME name. */
		logWarningNL("Unknown file suffix '%s'.",
		    suffix.toUtf8().constData());
		return;
	}

	if (Q_UNLIKELY(!Isds::Attachment::expectedMimeTypeNamesForSuffix(suffix)
	        .contains(mimeName))) {
		/* Replace detected MIME name with an alternative one. */
		QString suggestedMimeName =
		    Isds::Attachment::suggestedMimeTypeName(suffix);
		if (!suggestedMimeName.isEmpty()) {
			/* Alternative MIME name found. */
			logWarningNL(
			    "Unexpected MIME name '%s' for suffix '%s'. Changing MIME name to '%s'.",
			    mimeName.toUtf8().constData(), suffix.toUtf8().constData(),
			    suggestedMimeName.toUtf8().constData());
			mimeName = macroStdMove(suggestedMimeName);
		}
	}
}

QString mimeNameString(const QFileInfo &fileInfo)
{
	const QMimeType mimeType = QMimeDatabase().mimeTypeForFile(fileInfo);
	if (mimeType.isValid()) {
		QString mimeName = mimeType.name();

		adjustMimeName(mimeName, fileInfo.suffix().toLower());

		return mimeName;
	}

	return QString();
}

QString mimeNameString(const QString &fileName, const QByteArray &data)
{
	if (!fileName.isEmpty() && !data.isEmpty()) {
		const QMimeType mimeType =
		    QMimeDatabase().mimeTypeForFileNameAndData(fileName, data);
		if (mimeType.isValid()) {
			QString mimeName = mimeType.name();

			adjustMimeName(mimeName,
			    fileName.split('.').last().toLower());

			return mimeName;
		}
	}

	return QString();
}

bool attachDocumentRequiresMimeString(const QString &mimeName)
{
	/*
	 * When sending XML requests to the eGov portals
	 * then the robots handling the requests are
	 * likely to discard them if the MIME type for
	 * the XML documents or ZIP archives isn't set.
	 */
	return (mimeName == QStringLiteral("application/xml"))
	    || (mimeName == QStringLiteral("text/xml"))
	    || (mimeName == QStringLiteral("application/zip"));
}
