/* 
-*- coding: latin-1 -*-

This file is part of RefactorErl.

RefactorErl is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

RefactorErl 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with RefactorErl.  If not, see <http://plc.inf.elte.hu/erlang/>.

The Original Code is RefactorErl.

The Initial Developer of the Original Code is Eötvös Loránd University.
Portions created  by Eötvös Loránd University and ELTE-Soft Ltd.
are Copyright 2007-2025 Eötvös Loránd University, ELTE-Soft Ltd.
and Ericsson Hungary. All Rights Reserved.
*/

package com.refactorerl.ui.logic.investigations;

import java.util.Collection;
import java.util.logging.Logger;

import com.ericsson.otp.erlang.OtpErlangAtom;
import com.ericsson.otp.erlang.OtpErlangBoolean;
import com.ericsson.otp.erlang.OtpErlangInt;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangPid;
import com.ericsson.otp.erlang.OtpErlangTuple;
import com.refactorerl.ui.common.OtpErlangHelper;
import com.refactorerl.ui.communication.ReferlProxy;
import com.refactorerl.ui.communication.exceptions.CommunicationException;
import com.refactorerl.ui.communication.exceptions.ConnectionException;
import com.refactorerl.ui.communication.exceptions.RequestException;
import com.refactorerl.ui.logic.AbstractRequest;
import com.refactorerl.ui.logic.DatabaseHashRequest;

/** Initialize with the static factory method */
public class SaveInvestigationRequest extends AbstractRequest<Object> {

	private OtpErlangTuple request;

	public static SaveInvestigationRequest createSaveInvestigationRequest(Investigation investigation,
			ReferlProxy proxy, Logger logger) throws RequestException, ConnectionException, CommunicationException {

		OtpErlangTuple dbHash = new DatabaseHashRequest(proxy, logger).execute();

		return new SaveInvestigationRequest(investigation, dbHash, proxy, logger);

	}

	protected SaveInvestigationRequest(Investigation investigation, OtpErlangTuple databaseHash, ReferlProxy proxy,
			Logger logger) {
		super(proxy, logger);
		OtpErlangObject[] otpUsers = new OtpErlangObject[investigation.getUsers().size()];
		int i = 0;
		for (String user : investigation.getUsers()) {
			otpUsers[i] = OtpErlangHelper.toOtpErlangString(user);
			++i;
		}

		OtpErlangList otpInvDatas = translateInvestigationData(investigation);

		final OtpErlangTuple tuple = OtpErlangHelper.createTuple(new OtpErlangAtom("inv"), //$NON-NLS-1$
				OtpErlangHelper.toOtpErlangString(investigation.getName()), databaseHash, new OtpErlangList(otpUsers),
				otpInvDatas);
		request = new OtpErlangTuple(new OtpErlangObject[] { new OtpErlangAtom("insert_to_invtab"), tuple }); //$NON-NLS-1$

	}

	@Override
	protected OtpErlangObject doGetRequest() {
		return request;

	}

	private OtpErlangList translateInvestigationData(Investigation investigation) {
		Collection<InvestigationNode> nodes = investigation.getNodes();

		OtpErlangObject[] otpInvDatas = new OtpErlangObject[nodes.size()];

		int i = 0;
		for (InvestigationNode node : nodes) {
			OtpErlangPid pid = node.getPid();
			OtpErlangObject ppid = node.getParentPid() != null ? node.getParentPid() : new OtpErlangAtom("no_parent"); //$NON-NLS-1$

			for (InvestigationNode ch : node.children) {
				if (!node.childPids.contains(ch.pid)) {
					node.childPids.add(ch.pid);
					ch.parentPid = node.pid;
				}
			}

			OtpErlangList cpids = new OtpErlangList(node.getChildPids().toArray(
					new OtpErlangPid[node.getChildPids().size()]));

			OtpErlangTuple otpTextPos = node.memo ? new OtpErlangTuple(new OtpErlangObject[0]) : OtpErlangHelper
					.createTuple(new OtpErlangInt((int) node.textPosition.key), new OtpErlangInt(
							(int) node.textPosition.value));

			OtpErlangObject otpFileData = node.filePath == null ? new OtpErlangAtom("undefined") : OtpErlangHelper //$NON-NLS-1$
					.createTuple(OtpErlangHelper.toOtpErlangString(node.filePath), new OtpErlangInt(node.offset),
							new OtpErlangInt(node.lineNum), otpTextPos,
							OtpErlangHelper.toOtpErlangString(node.fileItemLabel));

			OtpErlangTuple otpScreenPos = OtpErlangHelper.createTuple(new OtpErlangInt((int) node.screenPosition.key),
					new OtpErlangInt((int) node.screenPosition.value));

			OtpErlangTuple invNode = OtpErlangHelper.createTuple(new OtpErlangAtom("invnode"), OtpErlangHelper //$NON-NLS-1$
					.toOtpErlangString(node.name), new OtpErlangBoolean(node.shown), node.graphNode, OtpErlangHelper
					.toOtpErlangString(node.text), node.label.equals("root") ? new OtpErlangAtom("root") //$NON-NLS-1$ //$NON-NLS-2$
					: OtpErlangHelper.toOtpErlangString(node.label), new OtpErlangBoolean(node.memo), otpFileData,
					otpScreenPos);
			otpInvDatas[i] = OtpErlangHelper.createTuple(pid, ppid, invNode, cpids);
			++i;
		}
		return new OtpErlangList(otpInvDatas);
	}

	@Override
	protected Object doProcessReply(OtpErlangObject m) {
		return null; 
	}

}
