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

import com.suse.salt.netapi.calls.WheelCall;

import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * salt.wheel.key
 */
public class Key {

    /**
     * Salt keys information.
     *
     * @param <T> type of data queried for each key state
     */
    public static abstract class Keys<T> {

        protected T local;

        protected T minions;

        @SerializedName("minions_pre")
        protected T unacceptedMinions;

        @SerializedName("minions_rejected")
        protected T rejectedMinions;

        @SerializedName("minions_denied")
        protected T deniedMinions;

        public T getLocal() {
            return local;
        }

        public T getMinions() {
            return minions;
        }

        public T getUnacceptedMinions() {
            return unacceptedMinions;
        }

        public T getRejectedMinions() {
            return rejectedMinions;
        }

        public T getDeniedMinions() {
            return deniedMinions;
        }
    }

    /**
     * Salt keys as returned by "key.list_all".
     */
    public static class Names extends Keys<List<String>> {

        public Names() {
            this.local = new LinkedList<>();
            this.minions = new LinkedList<>();
            this.unacceptedMinions = new LinkedList<>();
            this.rejectedMinions = new LinkedList<>();
            this.deniedMinions = new LinkedList<>();
        }
    }

    /**
     * Matching key fingerprints as returned by "key.finger".
     */
    public static class Fingerprints extends Keys<Map<String, String>> {

        public Fingerprints() {
            this.local = new HashMap<>();
            this.minions = new HashMap<>();
            this.unacceptedMinions = new HashMap<>();
            this.rejectedMinions = new HashMap<>();
            this.deniedMinions = new HashMap<>();
        }
    }

    private Key() {
    }

    private static final WheelCall<Names> LIST_ALL =
            new WheelCall<>("key.list_all", Optional.empty(), new TypeToken<Names>(){});

    public static WheelCall<Fingerprints> finger(String match) {
        Map<String, Object> args = new LinkedHashMap<>();
        args.put("match", match);
        return new WheelCall<>("key.finger", Optional.of(args),
                new TypeToken<Fingerprints>(){});
    }

    public static WheelCall<Object> accept(String match) {
        Map<String, Object> args = new LinkedHashMap<>();
        args.put("match", match);
        return new WheelCall<>("key.accept", Optional.of(args), new TypeToken<Object>(){});
    }

    public static WheelCall<Object> delete(String match) {
        Map<String, Object> args = new LinkedHashMap<>();
        args.put("match", match);
        return new WheelCall<>("key.delete", Optional.of(args), new TypeToken<Object>(){});
    }

    public static WheelCall<Object> reject(String match) {
        Map<String, Object> args = new LinkedHashMap<>();
        args.put("match", match);
        return new WheelCall<>("key.reject", Optional.of(args), new TypeToken<Object>(){});
    }

    public static WheelCall<Names> listAll() {
        return LIST_ALL;
    }
}

@@ -2097,32 +2097,338 @@
        %7D%0A    %7D%0A%0A
+    /**%0A     * A key pair as returned by gen() or gen_accept().%0A     */%0A    public static class Pair %7B%0A%0A        private String pub;%0A        private String priv;%0A%0A        public String getPub() %7B%0A            return pub;%0A        %7D%0A%0A        public String getPriv() %7B%0A            return priv;%0A        %7D%0A    %7D%0A%0A
     private Key(
@@ -2851,32 +2851,525 @@
 s%3E()%7B%7D);%0A    %7D%0A%0A
+    public static WheelCall%3CPair%3E gen(String id) %7B%0A        Map%3CString, Object%3E args = new LinkedHashMap%3C%3E();%0A        args.put(%22id_%22, id);%0A        return new WheelCall%3C%3E(%22key.gen%22, Optional.of(args), new TypeToken%3CPair%3E()%7B%7D);%0A    %7D%0A%0A    public static WheelCall%3CPair%3E genAccept(String id) %7B%0A        Map%3CString, Object%3E args = new LinkedHashMap%3C%3E();%0A        args.put(%22id_%22, id);%0A        return new WheelCall%3C%3E(%22key.gen_accept%22, Optional.of(args),%0A                new TypeToken%3CPair%3E()%7B%7D);%0A    %7D%0A%0A
     public stati

Implement support for gen() and gen_accept()