package me.rbrickis.mojo.parametric;

import me.rbrickis.mojo.parametric.binder.Binder;

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

public class ParametricRegistry implements Binder<Class<?>, ParameterResolver<?>> {

    private Map<Class<?>, ParameterResolver<?>> currentBindings = new HashMap<Class<?>, ParameterResolver<?>>();

    private Class<?> currentBind = null;

    public ParametricRegistry() {
        bind(String.class).to(argument -> argument);

        bind(Integer.TYPE).to(argument -> {
            int parsed = 0;
            try {
                parsed = Integer.parseInt(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Integer.class).to(argument -> {
            int parsed = 0;
            try {
                parsed = Integer.parseInt(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Float.TYPE).to(argument -> {
            float parsed = 0;
            try {
                parsed = Float.parseFloat(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Float.class).to(argument -> {
            float parsed = 0;
            try {
                parsed = Float.parseFloat(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Double.TYPE).to(argument -> {
            Double parsed = 0d;
            try {
                parsed = Double.parseDouble(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Double.class).to(argument -> {
            Double parsed = 0d;
            try {
                parsed = Double.parseDouble(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Long.TYPE).to(argument -> {
            Long parsed = 0L;
            try {
                parsed = Long.parseLong(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Long.class).to(argument -> {
            Long parsed = 0L;
            try {
                parsed = Long.parseLong(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Byte.TYPE).to(argument -> {
            Byte parsed = 0x0;
            try {
                parsed = Byte.parseByte(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Byte.class).to(argument -> {
            Byte parsed = 0x0;
            try {
                parsed = Byte.parseByte(argument);
            } catch (NumberFormatException ex) {
                ex.printStackTrace();
            }
            return parsed;
        });

        bind(Boolean.TYPE).to(argument -> {
            boolean parsed = false;
            if (argument.equalsIgnoreCase("true") || argument.equalsIgnoreCase("yes")) {
                parsed = true;
            } else if (argument.equalsIgnoreCase("false") || argument.equalsIgnoreCase("no")) {
                parsed = false;
            }
            return parsed;
        });

        bind(Boolean.class).to(argument -> {
            boolean parsed = false;
            if (argument.equalsIgnoreCase("true") || argument.equalsIgnoreCase("yes")) {
                parsed = true;
            } else if (argument.equalsIgnoreCase("false") || argument.equalsIgnoreCase("no")) {
                parsed = false;
            }
            return parsed;
        });

    }

    public Binder<Class<?>, ParameterResolver<?>> bind(Class<?> bind) {
        this.currentBind = bind;
        return this;
    }

    public void to(ParameterResolver<?> to) {
        if (currentBind == null) {
            throw new IllegalArgumentException("currentBind is null!");
        } else {
            currentBindings.put(currentBind, to);
            currentBind = null;
        }
    }

    public Map<Class<?>, ParameterResolver<?>> getBindings() {
        return currentBindings;
    }

    public ParameterResolver<?> get(Class<?> clazz) {
        if (!currentBindings.containsKey(clazz)) {
            throw new IllegalArgumentException("Could not find resolver for " + clazz.getSimpleName() + ".class");
        }
        return currentBindings.get(clazz);
    }
}

@@ -779,258 +779,41 @@
 .to(
-argument -%3E %7B%0A            int parsed = 0;%0A            try %7B%0A                parsed = Integer.parseInt(argument);%0A            %7D catch (NumberFormatException ex) %7B%0A                ex.printStackTrace();%0A            %7D%0A            return parsed;%0A        %7D
+currentBindings.get(Integer.TYPE)
 );%0A%0A
@@ -1129,260 +1129,39 @@
 .to(
-argument -%3E %7B%0A            float parsed = 0;%0A            try %7B%0A                parsed = Float.parseFloat(argument);%0A            %7D catch (NumberFormatException ex) %7B%0A                ex.printStackTrace();%0A            %7D%0A            return parsed;%0A        %7D
+currentBindings.get(Float.TYPE)
 );%0A%0A
@@ -1483,264 +1483,40 @@
 .to(
-argument -%3E %7B%0A            Double parsed = 0d;%0A            try %7B%0A                parsed = Double.parseDouble(argument);%0A            %7D catch (NumberFormatException ex) %7B%0A                ex.printStackTrace();%0A            %7D%0A            return parsed;%0A        %7D
+currentBindings.get(Double.TYPE)
 );%0A%0A
@@ -1828,260 +1828,42 @@
 .to(
-argument -%3E %7B%0A            Long parsed = 0L;%0A            try %7B%0A                parsed = Long.parseLong(argument);%0A            %7D catch (NumberFormatException ex) %7B%0A                ex.printStackTrace();%0A            %7D%0A            return parsed;%0A        %7D);
+currentBindings.get(Long.TYPE));%0A%0A
 %0A%0A  
@@ -2174,259 +2174,38 @@
 .to(
-argument -%3E %7B%0A            Byte parsed = 0x0;%0A            try %7B%0A                parsed = Byte.parseByte(argument);%0A            %7D catch (NumberFormatException ex) %7B%0A                ex.printStackTrace();%0A            %7D%0A            return parsed;%0A        %7D
+currentBindings.get(Byte.TYPE)
 );%0A%0A
@@ -2621,356 +2621,41 @@
 .to(
-argument -%3E %7B%0A            boolean parsed = false;%0A            if (argument.equalsIgnoreCase(%22true%22) %7C%7C argument.equalsIgnoreCase(%22yes%22)) %7B%0A                parsed = true;%0A            %7D else if (argument.equalsIgnoreCase(%22false%22) %7C%7C argument.equalsIgnoreCase(%22no%22)) %7B%0A                parsed = false;%0A            %7D%0A            return parsed;%0A        %7D
+currentBindings.get(Boolean.TYPE)
 );%0A%0A

Clean up code