package com.wizzardo.http.framework;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by wizzardo on 21.05.15.
 */
public abstract class MessageSource {
    public abstract String get(String key, Object... args);

    public String getWithDefault(String key, String def, Object... args) {
        String s = get(key, args);
        return s == null ? def : s;
    }

    static class Template {

        static final Pattern ARGS_PATTERN = Pattern.compile("\\{([0-9]+)\\}");

        final String raw;
        Part[] parts;

        public Template(String message) {
            raw = message;
            init();
        }

        public String get(Object... args) {
            StringBuilder sb = new StringBuilder();
            appendTo(sb::append, args);
            return sb.toString();
        }

        public void appendTo(Consumer<String> consumer, Object... args) {
            for (Part part : parts) {
                consumer.accept(part.get(args));
            }
        }

        protected void init() {
            try {
                List<Part> l = new ArrayList<>();

                Matcher matcher = ARGS_PATTERN.matcher(raw);
                int from = 0;
                while (matcher.find()) {
                    if (matcher.start() != from)
                        l.add(new TextPart(raw.substring(from, matcher.start())));

                    int number = Integer.parseInt(matcher.group(1));
                    l.add(new ArgumentPart(number));

                    from = matcher.end();
                }
                if (from != raw.length())
                    l.add(new TextPart(raw.substring(from)));

                parts = l.toArray(new Part[l.size()]);
            } catch (Exception e) {
                throw new IllegalArgumentException("can't prepare message '" + raw + "'");
            }
        }

        interface Part {
            String get(Object[] args);
        }

        static class TextPart implements Part {
            String value;

            public TextPart(String value) {
                this.value = value;
            }

            public String get(Object[] args) {
                return value;
            }
        }

        static class ArgumentPart implements Part {
            int i;

            public ArgumentPart(int i) {
                this.i = i;
            }

            public String get(Object[] args) {
                return args.length <= i ? "null" : String.valueOf(args[i]);
            }
        }

    }
}

@@ -1385,16 +1385,18 @@
 != from)
+ %7B
 %0A       
@@ -1412,35 +1412,31 @@
         
-l.add(new TextPart(
+String value = 
 raw.subs
@@ -1463,19 +1463,85 @@
 start())
-));
+;%0A                        l.add(args -%3E value);%0A                    %7D
 %0A%0A      
@@ -1633,31 +1633,76 @@
 add(
-new ArgumentPart(
+args -%3E args.length %3C= number ? %22null%22 : String.valueOf(args%5B
 number
+%5D
 ));%0A
@@ -1803,16 +1803,18 @@
 ength())
+ %7B
 %0A       
@@ -1830,49 +1830,103 @@
     
-l.add(new TextPart(raw.substring(from)));
+String value = raw.substring(from);%0A                    l.add(args -%3E value);%0A                %7D
 %0A%0A  
@@ -2208,585 +2208,8 @@
   %7D%0A
-%0A        static class TextPart implements Part %7B%0A            String value;%0A%0A            public TextPart(String value) %7B%0A                this.value = value;%0A            %7D%0A%0A            public String get(Object%5B%5D args) %7B%0A                return value;%0A            %7D%0A        %7D%0A%0A        static class ArgumentPart implements Part %7B%0A            int i;%0A%0A            public ArgumentPart(int i) %7B%0A                this.i = i;%0A            %7D%0A%0A            public String get(Object%5B%5D args) %7B%0A                return args.length %3C= i ? %22null%22 : String.valueOf(args%5Bi%5D);%0A            %7D%0A        %7D%0A%0A
     

rewrite to lambdas