package org.requirementsascode;

import static org.requirementsascode.ModelElementContainer.findModelElement;
import static org.requirementsascode.ModelElementContainer.hasModelElement;
import static org.requirementsascode.ModelElementContainer.saveModelElement;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

public class UseCaseModel {
	private Map<String, Actor> nameToActorMap;
	private Map<String, UseCase> nameToUseCaseMap;
	private UseCaseRunner useCaseRunner;
	private Actor systemActor;
	
	UseCaseModel(UseCaseRunner useCaseModelRun) {
		this.nameToActorMap = new HashMap<>();
		this.nameToUseCaseMap = new HashMap<>();
		this.systemActor = newActor("Autonomous System Reaction Actor");
		this.useCaseRunner = useCaseModelRun;
	}

	public boolean hasActor(String actorName) {		
		boolean hasActor = hasModelElement(actorName, nameToActorMap);
		return hasActor;
	}

	public boolean hasUseCase(String useCaseName) {		
		boolean hasUseCase = hasModelElement(useCaseName, nameToUseCaseMap);
		return hasUseCase;
	}
	
	public Actor newActor(String actorName) {
		Actor actor = new Actor(actorName, this);
		saveModelElement(actor, nameToActorMap);
		return actor;
	}

	public UseCase newUseCase(String useCaseName) {		
		UseCase useCase = new UseCase(useCaseName, this);
		saveModelElement(useCase, nameToUseCaseMap);
		return useCase;
	}
	
	public Optional<Actor> findActor(String actorName) {
		Optional<Actor> actor = findModelElement(actorName, nameToActorMap);
		return actor;
	}

	public Optional<UseCase> findUseCase(String useCaseName) {
		Optional<UseCase> useCase = findModelElement(useCaseName, nameToUseCaseMap);
		return useCase;
	}

	public Collection<Actor> getActors() {
		return Collections.unmodifiableCollection(nameToActorMap.values());
	}

	public Collection<UseCase> getUseCases() {
		return Collections.unmodifiableCollection(nameToUseCaseMap.values());
	}
	
	public Set<UseCaseStep> getUseCaseSteps() {
		return getUseCases().stream()
			.map(useCase -> useCase.getSteps())
			.flatMap(steps -> steps.stream())
			.collect(Collectors.toSet());
	}
	
	public UseCaseRunner getUseCaseRunner() {
		return useCaseRunner;
	}

	public Actor getSystemActor() {
		return systemActor;
	}
}

@@ -95,32 +95,109 @@
 ndModelElement;%0A
+import static org.requirementsascode.ModelElementContainer.getModelElements;%0A
 import static or
@@ -355,48 +355,15 @@
 til.
-Collection;%0Aimport java.util.Collections
+HashMap
 ;%0Aim
@@ -369,39 +369,36 @@
 mport java.util.
-HashMap
+List
 ;%0Aimport java.ut
@@ -1841,26 +1841,20 @@
 %09public 
-Collection
+List
 %3CActor%3E 
@@ -1880,42 +1880,24 @@
 urn 
-Collections.unmodifiableCollection
+getModelElements
 (nam
@@ -1907,25 +1907,16 @@
 ActorMap
-.values()
 );%0A%09%7D%0A%0A%09
@@ -1922,26 +1922,20 @@
 %09public 
-Collection
+List
 %3CUseCase
@@ -1965,42 +1965,24 @@
 urn 
-Collections.unmodifiableCollection
+getModelElements
 (nam
@@ -1998,17 +1998,8 @@
 eMap
-.values()
 );%0A%09

Refactor to use getModelElements method