package com.fluentinterface.utils;

import com.fluentinterface.builder.Builder;

import java.util.HashMap;
import java.util.Map;

/**
 * Utility builder to create a map with a fluent API. Because this builder implements the <pre>{@code Builder<>}</pre> interface, it can
 * be used directly in other builders as parameters, without the need to call `build()`.
 * <p>
 * Direct usage:
 * <pre>{@code
 * mappingof("key", 2).and("other", 3).build();
 * }</pre>
 * <p>
 * Usage within other builders:
 * <pre>{@code
 * class Person {
 *  public Map<String, Integer> details;
 * }
 *
 * interface PersonBuilder extends Builder<Person> {
 *      PersonBuilder withDetails(MapBuilder<String, Integer> details);
 * }
 *
 * aPerson().withDetails(mappingOf("playerNumber", 1929).and("attribute", 12993))
 * }</pre>
 *
 * @param <K> type for the map's keys
 * @param <V> type for the map's values
 */
public class MapBuilder<K, V> implements Builder<Map<K, V>> {

    private Map<K, V> built = new HashMap<>();

    private MapBuilder() {
    }

    private MapBuilder(K initialKey, V initialValue) {
        built.put(initialKey, initialValue);
    }

    public MapBuilder<K, V> and(K key, V value) {
        built.put(key, value);
        return this;
    }

    public MapBuilder<K, V> with(K key, V value) {
        built.put(key, value);
        return this;
    }

    public static <K, V> MapBuilder<K, V> mappingOf(K key, V value) {
        return new MapBuilder<>(key, value);
    }

    public static MapBuilder<Object, Object> map() {
        return new MapBuilder<>();
    }

    @Override
    public Map<K, V> build(Object... ignored) {
        return built;
    }
}

@@ -1024,114 +1024,93 @@
 () %7B
+%7D%0A
 %0A    
-%7D%0A%0A    private MapBuilder(K initialKey, V initialValue) %7B%0A        built.put(initialKey, initialValue)
+@Override%0A    public Map%3CK, V%3E build(Object... ignored) %7B%0A        return built
 ;%0A  
@@ -1325,32 +1325,139 @@
 rn this;%0A    %7D%0A%0A
+    private MapBuilder(K initialKey, V initialValue) %7B%0A        built.put(initialKey, initialValue);%0A    %7D%0A%0A
     public stati
@@ -1579,16 +1579,23 @@
 c static
+ %3CK, V%3E
  MapBuil
@@ -1602,132 +1602,784 @@
 der%3C
-Object, Object%3E map() %7B%0A        return new MapBuilder%3C%3E();%0A    %7D%0A%0A    @Override%0A    public Map%3CK, V%3E b
+K, V%3E mapOf(K key, V value) %7B%0A        return mappingOf(key, value);%0A    %7D%0A%0A    public static %3CK, V%3E MapBuilder%3CK, V%3E mapOf(K k1, V v1, K k2, V v2) %7B%0A        return mappingOf(k1, v1).and(k2, v2);%0A    %7D%0A%0A    public static %3CK, V%3E MapBuilder%3CK, V%3E mapOf(K k1, V v1, K k2, V v2, K k3, V v3) %7B%0A        return mappingOf(k1, v1).and(k2, v2).and(k3, v3);%0A    %7D%0A%0A    public static %3CK, V%3E MapBuilder%3CK, V%3E mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) %7B%0A        return mappingOf(k1, v1).and(k2, v2).and(k3, v3).and(k4, v4);%0A    %7D%0A%0A    public static %3CK, V%3E MapBuilder%3CK, V%3E mapOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) %7B%0A        return mappingOf(k1, v1).and(k2, v2).and(k3, v3).and(k4, v4).and(k5, v5);%0A    %7D%0A%0A    public static MapB
 uild
-(
+er%3C
 Object
-... ignored
+, Object%3E map(
 ) %7B%0A
@@ -2385,31 +2385,44 @@
 %0A        return 
-built
+new MapBuilder%3C%3E()
 ;%0A    %7D%0A%7D%0A

Add utility methods in `MapBuilder` to build maps with up to 5 entries