package com.suse.salt.netapi.calls.modules;

import com.suse.salt.netapi.calls.LocalCall;
import com.suse.salt.netapi.parser.JsonParser;
import com.suse.salt.netapi.results.StateApplyResult;

import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * salt.modules.state
 */
public class State {

    /**
     * Result type for state.apply
     */
    public static class ApplyResult extends StateApplyResult<JsonElement> {

        public <R> R getChanges(Class<R> dataType) {
            return JsonParser.GSON.fromJson(changes, dataType);
        }

        public <R> R getChanges(TypeToken<R> dataType) {
            return JsonParser.GSON.fromJson(changes, dataType.getType());
        }
    }

    private State() { }

    public static LocalCall<Map<String, ApplyResult>> apply(List<String> mods) {
        return apply(mods, Optional.empty(), Optional.empty());
    }

    public static LocalCall<Map<String, ApplyResult>> apply(String... mods) {
        return apply(Arrays.asList(mods), Optional.empty(), Optional.empty());
    }

    public static LocalCall<Map<String, ApplyResult>> apply(List<String> mods,
            Optional<Map<String, Object>> pillar, Optional<Boolean> queue) {
        Map<String, Object> kwargs = new LinkedHashMap<>();
        kwargs.put("mods", mods);
        pillar.ifPresent(p -> kwargs.put("pillar", p));
        queue.ifPresent(q -> kwargs.put("queue", q));
        return new LocalCall<>("state.apply", Optional.empty(), Optional.of(kwargs),
                new TypeToken<Map<String, ApplyResult>>(){});
    }

    public static LocalCall<Object> showHighstate() {
        return new LocalCall<>("state.show_highstate", Optional.empty(), Optional.empty(),
                new TypeToken<Object>(){});
    }

}

@@ -992,32 +992,50 @@
 ptional.empty(),
+ Optional.empty(),
  Optional.empty(
@@ -1174,32 +1174,66 @@
 ptional.empty(),
+ Optional.empty(),%0A               
  Optional.empty(
@@ -1395,16 +1395,52 @@
 n%3E queue
+,%0A            Optional%3CBoolean%3E test
 ) %7B%0A    
@@ -1635,24 +1635,76 @@
 ueue%22, q));%0A
+        test.ifPresent(t -%3E kwargs.put(%22test%22, t));%0A
         retu

Support the test parameter on state.apply