package org.requirementsascode.extract.freemarker.methodmodel;

import static org.requirementsascode.extract.freemarker.methodmodel.util.Steps.getFlowFromFreemarker;
import static org.requirementsascode.extract.freemarker.methodmodel.util.Words.getLowerCaseWordsOfClassName;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.requirementsascode.Condition;
import org.requirementsascode.Flow;
import org.requirementsascode.Step;
import org.requirementsascode.flowposition.After;
import org.requirementsascode.flowposition.FlowPosition;

import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;

public class FlowCondition implements TemplateMethodModelEx {
    private static final String WHEN = "when ";
    private static final String PREDICATE_SEPARATOR = ", ";
    private static final String PREDICATE_POSTFIX = ": ";

    @SuppressWarnings("rawtypes")
    @Override
    public Object exec(List arguments) throws TemplateModelException {
	if (arguments.size() != 1) {
	    throw new TemplateModelException("Wrong number of arguments. Must be 1.");
	}

	Flow flow = getFlowFromFreemarker(arguments.get(0));

	String flowPredicate = getFlowPredicate(flow);

	return new SimpleScalar(flowPredicate);
    }

    private String getFlowPredicate(Flow flow) {
	String predicate = getFlowPosition(flow) + getFlowPredicateSeparator(flow, PREDICATE_SEPARATOR) + getCondition(flow);
	String sep = "".equals(predicate) ? "" : PREDICATE_POSTFIX;
	String capitalizedPredicateWithColon = StringUtils.capitalize(predicate) + sep;
	return capitalizedPredicateWithColon;
    }

    private String getFlowPosition(Flow flow) {
	FlowPosition flowPosition = flow.getFlowPosition();
	String result = "";

	if (flowPosition != null) {
	    Step step = flowPosition.getStep();
	    boolean isNonDefaultFlowPosition = isNonDefaultFlowCondition(flowPosition, step);
	    if (isNonDefaultFlowPosition) {
		String stepName = step != null? step.getName() : "";
		String flowPositionWords = getLowerCaseWordsOfClassName(flowPosition.getClass());
		String flowPositionWithStepName = flowPositionWords + " " + stepName;
		result = flowPositionWithStepName.trim();
	    }
	}
	return result;
    }

    boolean isNonDefaultFlowCondition(FlowPosition flowPosition, Step step) {
	return !After.class.equals(flowPosition.getClass()) || step != null;
    }

    private String getFlowPredicateSeparator(Flow flow, String sep) {
	String flowPosition = getFlowPosition(flow);
	String result = "";
	if (flowPosition != "" && getCondition(flow) != "") {
	    result = sep;
	}
	return result;
    }

    private String getCondition(Flow flow) {
	String conditionWords = "";
	if (flow.getCondition().isPresent()) {
	    Condition condition = flow.getCondition().get();
	    conditionWords = WHEN + getLowerCaseWordsOfClassName(condition.getClass());
	}
	return conditionWords;
    }
}

@@ -342,49 +342,8 @@
 ls;%0A
-import org.requirementsascode.Condition;%0A
 impo
@@ -374,16 +374,16 @@
 e.Flow;%0A
+
 import o
@@ -1420,17 +1420,19 @@
 PARATOR)
- 
+%0A%09%09
 + getCon
@@ -1982,16 +1982,17 @@
  != null
+ 
 ? step.g
@@ -2701,25 +2701,16 @@
 Words = 
-%22%22;%0A%09if (
 flow.get
@@ -2724,83 +2724,16 @@
 on()
-.isPresent()) %7B%0A%09    Condition condition = flow.getCondition().get();%0A%09    
+%0A%09%09.map(
 cond
@@ -2737,24 +2737,21 @@
 ondition
-Words = 
+ -%3E (
 WHEN + g
@@ -2799,20 +2799,30 @@
 Class())
-;%0A%09%7D
+)).orElse(%22%22);
 %0A%09return

Improve style (dealing with Optional)