package org.hisp.dhis.rules;

import com.google.auto.value.AutoValue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Nonnull;

@AutoValue
abstract class RuleFunctionCall {
    private static final Pattern JUST_PARAMS_PATTERN = Pattern.compile("(^[^\\(]+\\()|\\)");
    private static final Pattern SPLIT_PARAMS_PATTERN = Pattern.compile("(('[^']+')|([^,]+))");

    @Nonnull
    public abstract String functionCall();

    @Nonnull
    public abstract String functionName();

    @Nonnull
    public abstract List<String> arguments();

    @Nonnull
    static RuleFunctionCall from(@Nonnull String functionCall) {
        if (functionCall == null) {
            throw new NullPointerException("functionCall == null");
        }

        Matcher functionNameMatcher = RuleExpression
                .FUNCTION_PATTERN_COMPILED.matcher(functionCall);

        if (!functionNameMatcher.find()) {
            throw new IllegalArgumentException("Malformed function call");
        }

        // Function name which later can be used for looking up functions
        String functionName = functionNameMatcher.group(1);

        // strip all special characters and leave just parameters
        String justParameters = JUST_PARAMS_PATTERN.matcher(functionCall).replaceAll("");

        // match each parameter
        Matcher splitParametersMatcher = SPLIT_PARAMS_PATTERN.matcher(justParameters);

        // aggregate matched parameters into list
        List<String> params = new ArrayList<>();
        while (splitParametersMatcher.find()) {
            String param = splitParametersMatcher.group().trim();
            if (!param.equals("")) params.add(param);
        }

        return new AutoValue_RuleFunctionCall(functionCall, String.format(Locale.US,
                "d2:%s", functionName), Collections.unmodifiableList(params));
    }
}
@@ -1766,21 +1766,18 @@
 f (!
-param
+%22%22
 .equals(
 %22%22))
@@ -1776,12 +1776,33 @@
 als(
-%22%22))
+param)) %7B%0A               
  par
@@ -1817,16 +1817,30 @@
 param);%0A
+            %7D%0A
         

fix pmd