/*****************************************************************************
* Copyright (c)2020 CEA LIST, Committer Name, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* CEA LIST - Initial API and implementation
* Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr 
* Gabriel Pedroza (CEA LIST) gabriel.pedroza@cea.fr 
*****************************************************************************/
package org.eclipse.pdp4eng.req.gdprananalysis.internal;

import java.util.HashSet;
import java.util.Iterator;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.DataSubject;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.PersonalData;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Purpose;
import org.eclipse.papyrus.pdp4eng.req.gdprananalysis.api.IRequirementGenerator;
import org.eclipse.papyrus.pdp4eng.req.profile.pdp4engReqGDPR.GeneratedRequirements;
import org.eclipse.papyrus.pdp4eng.req.profile.pdp4engReqGDPR.ProcessRequirement;
import org.eclipse.papyrus.requirements.sysml14.assistant.commands.api.RequirementCommandAssistantFactory;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.util.UMLUtil;

/**
 * this is an implmentation fo create requirements
 * {@link RequirementTestGenerator}
 *
 */
public class RequirementTestGeneratorImpl implements IRequirementGenerator {

	protected RequirementCommandAssistantFactory factory = new RequirementCommandAssistantFactory();
	protected int index=0;
	protected String prefix="GDPRReq-";
	protected Package generatedRequirementPackage=null;

	

	@Override
	public Command generateArticle51a(TransactionalEditingDomain domain, Package owner) {
		CompoundCommand compoundCommand= new CompoundCommand();
		Iterator<EObject> iterator=owner.eAllContents();

		while (iterator.hasNext()) {
			EObject eObject = (EObject) iterator.next();
			if( eObject  instanceof NamedElement) {
				NamedElement namedElement= (NamedElement)eObject;
				ProcessRequirement processRequirement= (ProcessRequirement)UMLUtil.getStereotypeApplication(namedElement, ProcessRequirement.class);
				if (processRequirement!=null) {
					HashSet<DataSubject> dataSubjectList=new HashSet<>();
					for (PersonalData personalData : processRequirement.getPersonaldata()) {
						dataSubjectList.addAll(personalData.getRelatedTo());
					}
					for (DataSubject dataSubject : dataSubjectList) {
						index++;
						String id = prefix+index;
						Command cmd=new LawfulRequirementCreateCommand(domain, lookForGeneratedrequirementPackage(owner), id, "",processRequirement, dataSubject);
						compoundCommand.append(cmd);
						index++;
						id = prefix+index;
						cmd=new FairlyRequirementCreateCommand(domain, lookForGeneratedrequirementPackage(owner), id, "",processRequirement, dataSubject);
						compoundCommand.append(cmd);
						index++;
						id = prefix+index;
						cmd=new TransparentRequirementCreateCommand(domain, lookForGeneratedrequirementPackage(owner), id, "",processRequirement, dataSubject);
						compoundCommand.append(cmd);
					}


				}
			}

		}
		return compoundCommand;
	}

	protected Package lookForGeneratedrequirementPackage(Package owner) {
		Iterator<EObject> iterator=owner.eAllContents();
		while (iterator.hasNext()) {
			EObject eObject = (EObject) iterator.next();
			if( eObject  instanceof Package) {
				NamedElement namedElement= (NamedElement)eObject;
				GeneratedRequirements generatedRequirements= (GeneratedRequirements)UMLUtil.getStereotypeApplication(namedElement, GeneratedRequirements.class);
				if (generatedRequirements!=null) {
					return (Package) namedElement;
				}
			}
		}
		return null;
	}

	@Override
	public Command generateArticle51b(TransactionalEditingDomain domain, Package owner) {
		//purpose Limitation
		CompoundCommand compoundCommand= new CompoundCommand();
		Iterator<EObject> iterator=owner.eAllContents();

		while (iterator.hasNext()) {
			EObject eObject = (EObject) iterator.next();
			if( eObject  instanceof NamedElement) {
				NamedElement namedElement= (NamedElement)eObject;
				PersonalData personalData= (PersonalData)UMLUtil.getStereotypeApplication(namedElement, PersonalData.class);
				if (personalData!=null) {
					for (org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process processElement : personalData.getProcessedBy()) {
						Purpose purpose=processElement.getContributedTo();
						index++;
						String id = prefix+index;
						Command cmd=new PurposeLimitationCreateCommand(domain, lookForGeneratedrequirementPackage(owner), id, "",personalData, purpose);
						compoundCommand.append(cmd);
					}
				}
			}
		}
		return compoundCommand;
	}

	@Override
	public Command generateArticle51d(TransactionalEditingDomain domain, Package owner) {
		//accuracy
		CompoundCommand compoundCommand= new CompoundCommand();
		Iterator<EObject> iterator=owner.eAllContents();

		while (iterator.hasNext()) {
			EObject eObject = (EObject) iterator.next();
			if( eObject  instanceof NamedElement) {
				NamedElement namedElement= (NamedElement)eObject;
				PersonalData personalData= (PersonalData)UMLUtil.getStereotypeApplication(namedElement, PersonalData.class);
				if (personalData!=null) {
					for (org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process processElement : personalData.getProcessedBy()) {
						Purpose purpose=processElement.getContributedTo();
						index++;
						String id = prefix+index;
						Command cmd=new AccuracyCreateCommand(domain, lookForGeneratedrequirementPackage(owner), id, "",personalData, purpose);
						compoundCommand.append(cmd);
					}
				}
			}
		}
		return compoundCommand;
	}

	@Override
	public Command generateArticle51e(TransactionalEditingDomain domain, Package owner) {
		// storage limitation
		CompoundCommand compoundCommand= new CompoundCommand();
		Iterator<EObject> iterator=owner.eAllContents();

		while (iterator.hasNext()) {
			EObject eObject = (EObject) iterator.next();
			if( eObject  instanceof NamedElement) {
				NamedElement namedElement= (NamedElement)eObject;
				PersonalData personalData= (PersonalData)UMLUtil.getStereotypeApplication(namedElement, PersonalData.class);
				if (personalData!=null) {
					for (org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process processElement : personalData.getProcessedBy()) {
						Purpose purpose=processElement.getContributedTo();
						index++;
						String id = prefix+index;
						Command cmd=new StorageLimitationCreateCommand(domain, lookForGeneratedrequirementPackage(owner), id, "",personalData, purpose);
						compoundCommand.append(cmd);
					}
				}
			}
		}
		return compoundCommand;
	}

	@Override
	public Command generateArticle51f(TransactionalEditingDomain domain, Package owner) {
		// integrity confidentiality
		CompoundCommand compoundCommand= new CompoundCommand();
		Iterator<EObject> iterator=owner.eAllContents();

		while (iterator.hasNext()) {
			EObject eObject = (EObject) iterator.next();
			if( eObject  instanceof NamedElement) {
				NamedElement namedElement= (NamedElement)eObject;
				ProcessRequirement processRequirement= (ProcessRequirement)UMLUtil.getStereotypeApplication(namedElement, ProcessRequirement.class);
				if (processRequirement!=null) {
					HashSet<DataSubject> dataSubjectList=new HashSet<>();
					for (PersonalData personalData : processRequirement.getPersonaldata()) {
						dataSubjectList.addAll(personalData.getRelatedTo());
					}
					for (DataSubject dataSubject : dataSubjectList) {
						index++;
						String id = prefix+index;
						Command cmd=new SecuritySafetyRequirementCreateCommand(domain, lookForGeneratedrequirementPackage(owner), id, "",processRequirement, dataSubject);
						compoundCommand.append(cmd);
						
					}


				}
			}

		}
		return compoundCommand;
	}

	@Override
	public Command generateArticle51c(TransactionalEditingDomain domain, Package owner) {
		// data minimisation
		CompoundCommand compoundCommand= new CompoundCommand();
		Iterator<EObject> iterator=owner.eAllContents();

		while (iterator.hasNext()) {
			EObject eObject = (EObject) iterator.next();
			if( eObject  instanceof NamedElement) {
				NamedElement namedElement= (NamedElement)eObject;
				PersonalData personalData= (PersonalData)UMLUtil.getStereotypeApplication(namedElement, PersonalData.class);
				if (personalData!=null) {
					for (org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process processElement : personalData.getProcessedBy()) {
						Purpose purpose=processElement.getContributedTo();
						index++;
						String id = prefix+index;
						Command cmd=new DataMinimizationCreateCommand(domain, lookForGeneratedrequirementPackage(owner), id, "",personalData, purpose);
						compoundCommand.append(cmd);
					}
				}
			}
		}
		return compoundCommand;
	}
}
