package stexfires.io.config;

import stexfires.core.TextRecord;
import stexfires.core.comparator.NULLS;
import stexfires.core.comparator.RecordComparators;
import stexfires.core.mapper.RecordMapper;
import stexfires.core.message.CompareMessageBuilder;
import stexfires.core.modifier.DistinctModifier;
import stexfires.core.modifier.MapModifier;
import stexfires.core.modifier.RecordStreamModifier;
import stexfires.core.modifier.SortModifier;
import stexfires.core.record.KeyValueRecord;
import stexfires.util.StringUnaryOperatorType;

import java.util.Comparator;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;

/**
 * @author Mathias Kalb
 * @since 0.1
 */
public class ConfigModifier<T extends TextRecord> implements RecordStreamModifier<T, KeyValueRecord> {

    protected final RecordStreamModifier<T, KeyValueRecord> modifier;

    public ConfigModifier(int keyIndex, int valueIndex, boolean removeDuplicates) {
        UnaryOperator<String> categoryOperator = c -> {
            String category = c;
            category = StringUnaryOperatorType.REMOVE_VERTICAL_WHITESPACE.operateString(category);
            category = StringUnaryOperatorType.TRIM_TO_NULL.operateString(category);
            category = StringUnaryOperatorType.UPPER_CASE.operateString(category); // TODO locale
            return category;
        };

        RecordMapper<T, KeyValueRecord> mapper = r -> new KeyValueRecord(
                categoryOperator.apply(r.getCategory()),
                r.getRecordId(),
                r.getValueAtOrElse(keyIndex, ConfigFileSpec.NULL_KEY),
                r.getValueAt(valueIndex));
        MapModifier<T, KeyValueRecord> mapModifier = new MapModifier<>(mapper);

        // TODO special category comparator (locale)
        Comparator<KeyValueRecord> recordComparator = RecordComparators
                .<KeyValueRecord>category(Comparator.naturalOrder(), NULLS.FIRST)
                .thenComparing(RecordComparators.valueOfKeyField(Comparator.naturalOrder()));
        SortModifier<KeyValueRecord> sortModifier = new SortModifier<>(recordComparator);

        DistinctModifier<KeyValueRecord> distinctModifier = new DistinctModifier<>(
                new CompareMessageBuilder()
                        .category()
                        .value(KeyValueRecord.KEY_INDEX));

        if (removeDuplicates) {
            modifier = mapModifier.andThen(sortModifier.andThen(distinctModifier));
        } else {
            modifier = mapModifier.andThen(sortModifier);
        }
    }

    @Override
    public Stream<KeyValueRecord> modify(Stream<T> recordStream) {
        return modifier.modify(recordStream);
    }

}

@@ -23,16 +23,59 @@
 onfig;%0A%0A
+import org.jetbrains.annotations.Nullable;%0A
 import s
@@ -92,32 +92,32 @@
 ore.TextRecord;%0A
-
 import stexfires
@@ -597,24 +597,49 @@
 Comparator;%0A
+import java.util.Locale;%0A
 import java.
@@ -997,32 +997,208 @@
 veDuplicates) %7B%0A
+        this(keyIndex, valueIndex, removeDuplicates, null);%0A    %7D%0A%0A    public ConfigModifier(int keyIndex, int valueIndex, boolean removeDuplicates, @Nullable Locale locale) %7B%0A
         UnaryOpe
@@ -1538,25 +1538,18 @@
 gory
-); // TODO
+,
  locale
+);
 %0A   
@@ -1949,61 +1949,8 @@
 );%0A%0A
-        // TODO special category comparator (locale)%0A
     
@@ -2280,24 +2280,60 @@
 mparator);%0A%0A
+        if (removeDuplicates) %7B%0A    
         Dist
@@ -2404,16 +2404,20 @@
 fier%3C%3E(%0A
+    
         
@@ -2476,16 +2476,20 @@
         
+    
 .categor
@@ -2492,16 +2492,20 @@
 egory()%0A
+    
         
@@ -2560,40 +2560,8 @@
 );%0A%0A
-        if (removeDuplicates) %7B%0A
     

Add new constructor with additional 'Locale' parameter