package org.vertexium.id;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.cache2k.Cache;
import org.cache2k.CacheBuilder;
import org.cache2k.CacheSource;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SimpleNameSubstitutionStrategy implements NameSubstitutionStrategy {
    private List<InflateItem> inflateSubstitutionList = new ArrayList<>();
    private List<DeflateItem> deflateSubstitutionList = new ArrayList<>();
    private final Cache<String, String> deflateCache;
    private final Cache<String, String> inflateCache;
    public static final String SUBS_DELIM = "\u0002";

    public SimpleNameSubstitutionStrategy() {
        deflateCache = CacheBuilder
                .newCache(String.class, String.class)
                .name(SimpleNameSubstitutionStrategy.class, "deflateCache-" + System.identityHashCode(this))
                .maxSize(1000)
                .source(new CacheSource<String, String>() {
                    @Override
                    public String get(String value) throws Throwable {
                        String deflatedVal = value;
                        for (DeflateItem deflateItem : deflateSubstitutionList) {
                            deflatedVal = deflateItem.deflate(deflatedVal);
                        }
                        inflateCache.put(deflatedVal, value);
                        return deflatedVal;
                    }
                })
                .build();

        inflateCache = CacheBuilder
                .newCache(String.class, String.class)
                .name(SimpleNameSubstitutionStrategy.class, "inflateCache-" + System.identityHashCode(this))
                .maxSize(1000)
                .source(new CacheSource<String, String>() {
                    @Override
                    public String get(String value) throws Throwable {
                        String inflatedValue = value;
                        for (InflateItem inflateItem : inflateSubstitutionList) {
                            inflatedValue = inflateItem.inflate(inflatedValue);
                        }
                        deflateCache.put(inflatedValue, value);
                        return inflatedValue;
                    }
                })
                .build();
    }

    @Override
    public void setup(Map config) {
        this.setSubstitutionList(SimpleSubstitutionUtils.getSubstitutionList(config));
    }

    @Override
    public String deflate(String value) {
        return deflateCache.get(value);
    }

    @Override
    public String inflate(String value) {
        return inflateCache.get(value);
    }

    public static String wrap(String str) {
        return SUBS_DELIM + str + SUBS_DELIM;
    }

    public void setSubstitutionList(List<Pair<String, String>> substitutionList) {
        this.inflateSubstitutionList.clear();
        this.deflateSubstitutionList.clear();
        for (Pair<String, String> pair : substitutionList) {
            this.inflateSubstitutionList.add(new InflateItem(wrap(pair.getValue()), pair.getKey()));
            this.deflateSubstitutionList.add(new DeflateItem(pair.getKey(), wrap(pair.getValue())));
        }
    }

    private static class InflateItem {
        private final String pattern;
        private final String replacement;

        public InflateItem(String pattern, String replacement) {
            this.pattern = pattern;
            this.replacement = replacement;
        }

        public String inflate(String value) {
            return StringUtils.replace(value, pattern, replacement);
        }
    }

    private static class DeflateItem {
        private final String pattern;
        private final String replacement;

        public DeflateItem(String pattern, String replacement) {
            this.pattern = pattern;
            this.replacement = replacement;
        }

        public String deflate(String value) {
            return StringUtils.replace(value, pattern, replacement);
        }
    }
}

@@ -978,1333 +978,335 @@
 new 
-CacheSource%3CString, String%3E() %7B%0A                    @Override%0A                    public String get(String value) throws Throwable %7B%0A                        String deflatedVal = value;%0A                        for (DeflateItem deflateItem : deflateSubstitutionList) %7B%0A                            deflatedVal = deflateItem.deflate(deflatedVal);%0A                        %7D%0A                        inflateCache.put(deflatedVal, value);%0A                        return deflatedVal;%0A                    %7D%0A                %7D)%0A                .build();%0A%0A        inflateCache = CacheBuilder%0A                .newCache(String.class, String.class)%0A                .name(SimpleNameSubstitutionStrategy.class, %22inflateCache-%22 + System.identityHashCode(this))%0A                .maxSize(1000)%0A                .source(new CacheSource%3CString, String%3E() %7B%0A                    @Override%0A                    public String get(String value) throws Throwable %7B%0A                        String inflatedValue = value;%0A                        for (InflateItem inflateItem : inflateSubstitutionList) %7B%0A                            inflatedValue = inflateItem.inflate(inflatedValue);%0A                        %7D%0A                        deflateCache.put(inflatedValue, value);%0A                        return inflatedValue;%0A                    %7D%0A                %7D
+DeflateCacheSource())%0A                .build();%0A%0A        inflateCache = CacheBuilder%0A                .newCache(String.class, String.class)%0A                .name(SimpleNameSubstitutionStrategy.class, %22inflateCache-%22 + System.identityHashCode(this))%0A                .maxSize(1000)%0A                .source(new InflateCacheSource()
 )%0A  
@@ -2662,385 +2662,1279 @@
 ate 
-static class DeflateItem %7B%0A        private final String pattern;%0A        private final String replacement;%0A%0A        public DeflateItem(String pattern, String replacement) %7B%0A            this.pattern = pattern;%0A            this.replacement = replacement;%0A        %7D%0A%0A        public String deflate(String value) %7B%0A            return StringUtils.replace(value, pattern, replacement)
+class InflateCacheSource implements CacheSource%3CString, String%3E %7B%0A        @Override%0A        public String get(String value) throws Throwable %7B%0A            String inflatedValue = value;%0A            for (InflateItem inflateItem : inflateSubstitutionList) %7B%0A                inflatedValue = inflateItem.inflate(inflatedValue);%0A            %7D%0A            deflateCache.put(inflatedValue, value);%0A            return inflatedValue;%0A        %7D%0A    %7D%0A%0A    private static class DeflateItem %7B%0A        private final String pattern;%0A        private final String replacement;%0A%0A        public DeflateItem(String pattern, String replacement) %7B%0A            this.pattern = pattern;%0A            this.replacement = replacement;%0A        %7D%0A%0A        public String deflate(String value) %7B%0A            return StringUtils.replace(value, pattern, replacement);%0A        %7D%0A    %7D%0A%0A    private class DeflateCacheSource implements CacheSource%3CString, String%3E %7B%0A        @Override%0A        public String get(String value) throws Throwable %7B%0A            String deflatedVal = value;%0A            for (DeflateItem deflateItem : deflateSubstitutionList) %7B%0A                deflatedVal = deflateItem.deflate(deflatedVal);%0A            %7D%0A            inflateCache.put(deflatedVal, value);%0A            return deflatedVal
 ;%0A  

refactor the code to be cleaner