/*
 * Copyright (C) 2014-2024 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 "src/datovka_shared/isds/message_interface.h"
#include "src/datovka_shared/log/log.h"
#include "src/records_management/content/automatic_upload_target.h"
#include "src/records_management/content/automatic_upload_target_interaction.h"

QString RecMgmt::uniqueUploadReceived(const Isds::Envelope &env,
    const RecMgmt::AutomaticUploadTarget &rmTgts, bool *ambiguous)
{
	bool amb = false;
	QString identUpload, refNumUpload;

	QString cId;
	QString caseUploadTgt;
	{
		const QString &ident = env.dmRecipientIdent();
		if (!ident.isEmpty()) {
			if (rmTgts.haveCaseId(ident)) {
				identUpload = rmTgts.hierarchyForCaseId(ident);
			} else if (rmTgts.haveAmbiguousCaseId(ident)) {
				amb = true;
				logWarningNL(
				    "Recipient identification file mark '%s' has ambiguous upload hierarchy target.",
				    ident.toUtf8().constData());
			}
		}

		const QString &refNum = env.dmRecipientRefNumber();
		if (!refNum.isEmpty()) {
			if (rmTgts.haveCaseId(refNum)) {
				refNumUpload = rmTgts.hierarchyForCaseId(refNum);
			} else if (rmTgts.haveAmbiguousCaseId(refNum)) {
				amb = true;
				logWarningNL(
				    "Recipient reference number '%s' has ambiguous upload hierarchy target.",
				    refNum.toUtf8().constData());
			}
		}

		if (identUpload == refNumUpload) {
			cId = ident;
			caseUploadTgt = identUpload;
		} else if ((!identUpload.isEmpty()) && refNumUpload.isEmpty()) {
			cId = ident;
			caseUploadTgt = identUpload;
		} else if (identUpload.isEmpty() && (!refNumUpload.isEmpty())) {
			cId = refNum;
			caseUploadTgt = refNumUpload;
		} else if ((!identUpload.isEmpty()) && (!refNumUpload.isEmpty())) {
			amb = true;
			logWarningNL(
			    "Recipient reference number '%s' and recipient identification file mark '%s' point to different upload hierarchy items '%s' and '%s'.",
			    refNum.toUtf8().constData(),
			    ident.toUtf8().constData(),
			    refNumUpload.toUtf8().constData(),
			    identUpload.toUtf8().constData());
		}
	}

	identUpload.clear();
	refNumUpload.clear();

	QString ccId;
	QString courtCaseUploadTgt;
	{
		const QString &ident = env.dmSenderIdent();
		if (!ident.isEmpty()) {
			if (rmTgts.haveCourtCaseId(ident)) {
				identUpload = rmTgts.hierarchyForCourtCaseId(ident);
			} else if (rmTgts.haveAmbiguousCourtCaseId(ident)) {
				amb = true;
				logWarningNL(
				    "Sender identification file mark '%s' has ambiguous upload hierarchy target.",
				    ident.toUtf8().constData());
			}
		}

		const QString &refNum = env.dmSenderRefNumber();
		if (!refNum.isEmpty()) {
			if (rmTgts.haveCourtCaseId(refNum)) {
				refNumUpload = rmTgts.hierarchyForCourtCaseId(refNum);
			} else if (rmTgts.haveAmbiguousCourtCaseId(refNum)) {
				amb = true;
				logWarningNL(
				    "Sender reference number '%s' has ambiguous upload hierarchy target.",
				    refNum.toUtf8().constData());
			}
		}

		if (identUpload == refNumUpload) {
			ccId = ident;
			courtCaseUploadTgt = identUpload;
		} else if ((!identUpload.isEmpty()) && refNumUpload.isEmpty()) {
			ccId = ident;
			courtCaseUploadTgt = identUpload;
		} else if (identUpload.isEmpty() && (!refNumUpload.isEmpty())) {
			ccId = refNum;
			courtCaseUploadTgt = refNumUpload;
		} else if ((!identUpload.isEmpty()) && (!refNumUpload.isEmpty())) {
			amb = true;
			logWarningNL(
			    "Sender reference number '%s' and sender identification file mark '%s' point to different upload hierarchy items '%s' and '%s'.",
			    refNum.toUtf8().constData(),
			    ident.toUtf8().constData(),
			    refNumUpload.toUtf8().constData(),
			    identUpload.toUtf8().constData());
		}
	}

	QString ret;

	if (caseUploadTgt.isEmpty() && courtCaseUploadTgt.isEmpty()) {
		/* Nothing definite found. */
	} else if ((!caseUploadTgt.isEmpty()) && (!courtCaseUploadTgt.isEmpty())) {
		if (caseUploadTgt == courtCaseUploadTgt) {
			ret = caseUploadTgt;
		} else {
			amb = true;
			logWarningNL(
			    "Recipient '%s' and sender '%s' identifiers point to different upload hierarchy items '%s' and '%s'.",
			    cId.toUtf8().constData(),
			    ccId.toUtf8().constData(),
			    caseUploadTgt.toUtf8().constData(),
			    courtCaseUploadTgt.toUtf8().constData());
		}
	} else if (!caseUploadTgt.isEmpty()) {
		ret = caseUploadTgt;
	} else if (!courtCaseUploadTgt.isEmpty()) {
		ret = courtCaseUploadTgt;
	}

	if (ambiguous != Q_NULLPTR) {
		*ambiguous = amb;
	}
	return ret;
}
