package com.tvd12.ezyfox.tool;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class EzyBuilderCreator {

	public String create(Class<?> clazz) throws Exception {
		StringBuilder classScript = new StringBuilder();
		StringBuilder builderScript = new StringBuilder();
		classScript.append("public class ")
			.append(clazz.getSimpleName())
			.append(" {\n\n");
		builderScript.append("public static class Builder implements EzyBuilder<")
				.append(clazz.getSimpleName())
			.append("> {\n\n");
		List<Field> fields = Arrays.stream(clazz.getDeclaredFields())
			.filter(f -> !Modifier.isStatic(f.getModifiers()))
			.collect(Collectors.toList());
		for(Field field : fields) {
			classScript.append("\t");
			int modifier = field.getModifiers();
			if(Modifier.isPrivate(modifier))
				classScript.append("private");
			else if(Modifier.isProtected(modifier))
				classScript.append("protected");
			else
				classScript.append("public");
			classScript
				.append(" final ")
				.append(field.getType().getSimpleName())
				.append(" ")
				.append(field.getName())
				.append(";\n");
		}
		classScript.append("\n\tprotected ").append(clazz.getSimpleName())
			.append("(Builder builder) {\n");
		for(Field field : fields) {
			classScript.append("\t\tthis.").append(field.getName())
				.append(" = builder.").append(field.getName())
				.append(";\n");
		}
		classScript.append("\t}");
		for(Field field : fields) {
			builderScript.append("\tprotected ")
				.append(field.getType().getSimpleName())
				.append(" ")
				.append(field.getName())
				.append(";\n");
		}
		builderScript.append("\n");
		for(Field field : fields) {
			builderScript.append("\tpublic Builder ")
				.append(field.getName())
				.append("(")
					.append(field.getType().getSimpleName())
					.append(" ").append(field.getName())
				.append(") {\n")
					.append("\t\tthis.").append(field.getName()).append(" = ").append(field.getName())
					.append(";\n")
					.append("\t\treturn this;")
				.append("\n\t}\n\n");
		}
		builderScript.append("\tpublic ").append(clazz.getSimpleName())
			.append(" build() {\n")
				.append("\t\treturn new ").append(clazz.getSimpleName()).append("(this);\n")
			.append("\t}"); 
		builderScript.append("\n\n}");
		return classScript
				.append("\n\n")
				.append("\tpublic static Builder builder() {\n")
				.append("\t\treturn new Builder();\n")
				.append("\t}\n\n")
				.append(EzyStringTool.tabAll(builderScript.toString(), 1))
				.append("\n\n")
				.append("}").toString();
	}
	
}

@@ -181,78 +181,406 @@
 s;%0A%0A
-public class EzyBuilderCreator %7B%0A%0A%09public String create(Class%3C?%3E clazz
+import com.tvd12.ezyfox.reflect.EzyField;%0A%0Apublic class EzyBuilderCreator %7B%0A%09%0A%09protected boolean buildBySetter;%0A%09%0A%09public EzyBuilderCreator buildBySetter(boolean buildBySetter) %7B%0A%09%09this.buildBySetter = buildBySetter;%0A%09%09return this;%0A%09%7D%0A%0A%09public String create(Class%3C?%3E clazz) throws Exception %7B%0A%09%09return create(clazz, %22Builder%22);%0A%09%7D%0A%09%0A%09public String create(%0A%09%09%09Class%3C?%3E clazz, String builderClassName
 ) th
@@ -838,23 +838,40 @@
 c class 
-B
+%22 + b
 uilder
+ClassName + %22
  impleme
@@ -2121,23 +2121,40 @@
 tpublic 
-B
+%22 + b
 uilder
+ClassName + %22
  %22)%0A%09%09%09%09
@@ -2559,37 +2559,476 @@
 (%22 build() %7B%5Cn%22)
+;
 %0A%09%09
-%09%09
+if(buildBySetter) %7B%0A%09%09%09builderScript.append(%22%5Ct%5Ct%22).append(clazz.getSimpleName())%0A%09%09%09%09.append(%22 p = new %22)%0A%09%09%09%09.append(clazz.getSimpleName()).append(%22();%5Cn%22);%0A%09%09%09for(Field field : fields) %7B%0A%09%09%09%09EzyField f = new EzyField(field);%0A%09%09%09%09builderScript.append(%22%5Ct%5Ctp.%22).append(f.getSetterMethod())%0A%09%09%09%09%09.append(%22(%22).append(f.getName()).append(%22);%22)%0A%09%09%09%09%09.append(%22%5Cn%22);%0A%09%09%09%7D%0A%09%09%09builderScript.append(%22%5Ct%5Ctreturn p;%5Cn%22);%0A%09%09%7D%0A%09%09else %7B%0A%09%09%09builderScript
 .append(%22%5Ct%5Ctret
@@ -3087,20 +3087,37 @@
 is);%5Cn%22)
+;
 %0A%09%09
-%09
+%7D%0A%09%09builderScript
 .append(
@@ -3228,23 +3228,40 @@
  static 
-B
+%22 + b
 uilder
+ClassName + %22
  builder
@@ -3297,23 +3297,40 @@
 urn new 
-B
+%22 + b
 uilder
+ClassName + %22
 ();%5Cn%22)%0A

update tools