/*******************************************************************************
 * Copyright (c) 2004, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.tools.internal;

import java.lang.reflect.*;
import java.util.*;

public class StructsGenerator extends JNIGenerator {

boolean header;

static final boolean GLOBAL_REF = false;

public StructsGenerator(boolean header) {
	this.header = header;
}

@Override
public void generateCopyright() {
	outputln(fixDelimiter(getMetaData().getCopyright()));
}

@Override
public void generateIncludes() {
	if (header) {
		output("#include \"");
		output(getOutputName());
		outputln(".h\"");
	} else {
		outputln("#include \"swt.h\"");
		output("#include \"");
		output(getOutputName());
		outputln("_structs.h\"");
	}
	outputln();
}

@Override
public void generate(JNIClass clazz) {
	int j = 0;
	JNIField[] fields = clazz.getDeclaredFields();
	for (; j < fields.length; j++) {
		JNIField field = fields[j];
		int mods = field.getModifiers();
		if ((mods & Modifier.PUBLIC) != 0 && (mods & Modifier.STATIC) == 0) {
			break;
		}
	}
	if (j == fields.length) return;
	if (header) {
		generateHeaderFile(clazz);
	} else {
		generateSourceFile(clazz);
	}
}

@Override
public void generate() {
	if (!header && getClasses().length == 0) return;
	super.generate();
}

@Override
public String getExtension() {
	return header ? ".h" : super.getExtension();
}

@Override
public String getSuffix() {
	return "_structs";
}

void generateExcludes(JNIClass[] classes) {
	HashSet<String> excludes = new HashSet<>();
	for (int i = 0; i < classes.length; i++) {
		JNIClass clazz = classes[i];
		String exclude = clazz.getExclude();
		if (exclude.length() != 0) {
			excludes.add(exclude);
		}
	}
	for (String exclude : excludes) {
		outputln(exclude);
		for (int i = 0; i < classes.length; i++) {
			JNIClass clazz = classes[i];
			String classExclude = clazz.getExclude();
			if (exclude.equals(classExclude)) {
				output("#define NO_");
				outputln(clazz.getSimpleName());
			}
		}
		outputln("#endif");
		outputln();
	}
}

void generateHeaderFile(JNIClass clazz) {
	generateSourceStart(clazz);
	generatePrototypes(clazz);
	generateBlankMacros(clazz);
	generateSourceEnd();	
	outputln();
}

void generateSourceFile(JNIClass clazz) {
	generateSourceStart(clazz);
	generateFIDsStructure(clazz);
	outputln();
	generateGlobalVar(clazz);
	outputln();
	generateFunctions(clazz);
	generateSourceEnd();
	outputln();
}

void generateSourceStart(JNIClass clazz) {
	String clazzName = clazz.getSimpleName();
	output("#ifndef NO_");
	outputln(clazzName);
}

void generateSourceEnd() {
	outputln("#endif");
}

void generateGlobalVar(JNIClass clazz) {
	String clazzName = clazz.getSimpleName();
	output(clazzName);
	output("_FID_CACHE ");
	output(clazzName);
	outputln("Fc;");
}

void generateBlankMacros(JNIClass clazz) {
	String clazzName = clazz.getSimpleName();
	outputln("#else");
	output("#define cache");
	output(clazzName);
	outputln("Fields(a,b)");
	output("#define get");
	output(clazzName);
	outputln("Fields(a,b,c) NULL");
	output("#define set");
	output(clazzName);
	outputln("Fields(a,b,c)");
	output("#define ");
	output(clazzName);
	outputln("_sizeof() 0");
}

void generatePrototypes(JNIClass clazz) {
	String clazzName = clazz.getSimpleName();
	output("void cache");
	output(clazzName);
	outputln("Fields(JNIEnv *env, jobject lpObject);");
	if (clazz.getFlag(Flags.FLAG_STRUCT)) {
		output("struct ");
	}
	output(clazzName);
	output(" *get");
	output(clazzName);
	output("Fields(JNIEnv *env, jobject lpObject, ");
	if (clazz.getFlag(Flags.FLAG_STRUCT)) {
		output("struct ");
	}
	output(clazzName);
	outputln(" *lpStruct);");
	output("void set");
	output(clazzName);
	output("Fields(JNIEnv *env, jobject lpObject, ");
	if (clazz.getFlag(Flags.FLAG_STRUCT)) {
		output("struct ");
	}
	output(clazzName);
	outputln(" *lpStruct);");
	output("#define ");
	output(clazzName);
	output("_sizeof() sizeof(");
	if (clazz.getFlag(Flags.FLAG_STRUCT)) {
		output("struct ");
	}
	output(clazzName);
	outputln(")");
}

void generateFIDsStructure(JNIClass clazz) {
	String clazzName = clazz.getSimpleName();
	output("typedef struct ");
	output(clazzName);
	outputln("_FID_CACHE {");
	outputln("\tint cached;");
	outputln("\tjclass clazz;");
	output("\tjfieldID ");
	JNIField[] fields = clazz.getDeclaredFields();
	boolean first = true;
	for (int i = 0; i < fields.length; i++) {
		JNIField field = fields[i];
		if (ignoreField(field)) continue;
		if (!first) output(", ");
		output(field.getName());
		first = false;
	}
	outputln(";");
	output("} ");
	output(clazzName);
	outputln("_FID_CACHE;");
}

void generateCacheFunction(JNIClass clazz) {
	String clazzName = clazz.getSimpleName();
	output("void cache");
	output(clazzName);
	outputln("Fields(JNIEnv *env, jobject lpObject)");
	outputln("{");
	output("\tif (");
	output(clazzName);
	outputln("Fc.cached) return;");
	JNIClass superclazz = clazz.getSuperclass();
	if (!superclazz.getName().equals("java.lang.Object")) {
		String superName = superclazz.getSimpleName();
		output("\tcache");
		output(superName);
		outputln("Fields(env, lpObject);");
	}
	output("\t");
	output(clazzName);
	boolean isCPP = getCPP();
	if (isCPP) {
		if (GLOBAL_REF) {
			output("Fc.clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(lpObject));");
		} else {
			output("Fc.clazz = env->GetObjectClass(lpObject);");
		}
	} else {
		if (GLOBAL_REF) {
			output("Fc.clazz = (*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, lpObject));");
		} else {
			output("Fc.clazz = (*env)->GetObjectClass(env, lpObject);");
		}
	}
	outputln();
	JNIField[] fields = clazz.getDeclaredFields();
	for (int i = 0; i < fields.length; i++) {
		JNIField field = fields[i];
		if (ignoreField(field)) continue;
		output("\t");
		output(clazzName);
		output("Fc.");
		output(field.getName());
		if (isCPP) {
			output(" = env->GetFieldID(");
		} else {
			output(" = (*env)->GetFieldID(env, ");
		}
		output(clazzName);
		output("Fc.clazz, \"");
		output(field.getName());
		JNIType type = field.getType(), type64 = field.getType64();
		output("\", ");
		if (type.equals(type64)) output("\"");
		output(type.getTypeSignature(!type.equals(type64)));
		if (type.equals(type64)) output("\"");
		outputln(");");
	}
	output("\t");
	output(clazzName);
	outputln("Fc.cached = 1;");
	outputln("}");
}

void generateGetFields(JNIClass clazz) {
	JNIClass superclazz = clazz.getSuperclass();
	String clazzName = clazz.getSimpleName();
	String superName = superclazz.getSimpleName();
	if (!superclazz.getName().equals("java.lang.Object")) {
		/* Windows exception - cannot call get/set function of super class in this case */
		if (!(clazzName.equals(superName + "A") || clazzName.equals(superName + "W"))) {
			output("\tget");
			output(superName);
			output("Fields(env, lpObject, (");
			output(superName);
			outputln(" *)lpStruct);");
		} else {
			generateGetFields(superclazz);
		}
	}
	JNIField[] fields = clazz.getDeclaredFields();
	for (int i = 0; i < fields.length; i++) {
		JNIField field = fields[i];
		if (ignoreField(field)) continue;
		String exclude = field.getExclude();
		if (exclude.length() != 0) {
			outputln(exclude);
		}
		boolean noWinCE = field.getFlag(FLAG_NO_WINCE);
		if (noWinCE) {
			outputln("#ifndef _WIN32_WCE");
		}
		JNIType type = field.getType(), type64 = field.getType64();
		String typeName = type.getSimpleName();
		String accessor = field.getAccessor();
		if (accessor == null || accessor.length() == 0) accessor = field.getName();
		boolean isCPP = getCPP();
		if (type.isPrimitive()) {
			output("\tlpStruct->");
			output(accessor);
			output(" = ");
			output(field.getCast());
			if (isCPP) {
				output("env->Get");
			} else {
				output("(*env)->Get");
			}
			output(type.getTypeSignature1(!type.equals(type64)));
			if (isCPP) {
				output("Field(lpObject, ");
			} else {
				output("Field(env, lpObject, ");
			}
			output(field.getDeclaringClass().getSimpleName());
			output("Fc.");
			output(field.getName());
			output(");");
		} else if (type.isArray()) {
			JNIType componentType = type.getComponentType(), componentType64 = type64.getComponentType();
			if (componentType.isPrimitive()) {
				outputln("\t{");
				output("\t");				
				output(type.getTypeSignature2(!type.equals(type64)));
				output(" lpObject1 = (");
				output(type.getTypeSignature2(!type.equals(type64)));
				if (isCPP) {
					output(")env->GetObjectField(lpObject, ");
				} else {
					output(")(*env)->GetObjectField(env, lpObject, ");
				}
				output(field.getDeclaringClass().getSimpleName());
				output("Fc.");
				output(field.getName());
				outputln(");");
				if (isCPP) {
					output("\tenv->Get");
				} else {
					output("\t(*env)->Get");
				}
				output(componentType.getTypeSignature1(!componentType.equals(componentType64)));
				if (isCPP) {
					output("ArrayRegion(lpObject1, 0, sizeof(lpStruct->");
				} else {
					output("ArrayRegion(env, lpObject1, 0, sizeof(lpStruct->");
				}
				output(accessor);
				output(")");
				if (!componentType.isType("byte")) {
					output(" / sizeof(");
					output(componentType.getTypeSignature2(!componentType.equals(componentType64)));
					output(")");
				}
				output(", (");
				output(type.getTypeSignature4(!type.equals(type64), false));
				output(")");
				if (field.getFlag(FLAG_STRUCT)) {
					output("&");
				}
				output("lpStruct->");
				output(accessor);
				outputln(");");
				output("\t}");
			} else {
				throw new Error("not done");
			}
		} else {
			outputln("\t{");
			if (isCPP) {
				output("\tjobject lpObject1 = env->GetObjectField(lpObject, ");
			} else {
				output("\tjobject lpObject1 = (*env)->GetObjectField(env, lpObject, ");
			}
			output(field.getDeclaringClass().getSimpleName());
			output("Fc.");
			output(field.getName());
			outputln(");");
			output("\tif (lpObject1 != NULL) get");
			output(typeName);
			output("Fields(env, lpObject1, &lpStruct->");
			output(accessor);
			outputln(");");
			output("\t}");
		}
		outputln();
		if (noWinCE) {
			outputln("#endif");
		}
		if (exclude.length() != 0) {
			outputln("#endif");
		}
	}
}

void generateGetFunction(JNIClass clazz) {
	String clazzName = clazz.getSimpleName();
	if (clazz.getFlag(Flags.FLAG_STRUCT)) {
		output("struct ");
	}
	output(clazzName);
	output(" *get");
	output(clazzName);
	output("Fields(JNIEnv *env, jobject lpObject, ");
	if (clazz.getFlag(Flags.FLAG_STRUCT)) {
		output("struct ");
	}
	output(clazzName);
	outputln(" *lpStruct)");
	outputln("{");
	output("\tif (!");
	output(clazzName);
	output("Fc.cached) cache");
	output(clazzName);
	outputln("Fields(env, lpObject);");
	generateGetFields(clazz);
	outputln("\treturn lpStruct;");
	outputln("}");
}

void generateSetFields(JNIClass clazz) {
	JNIClass superclazz = clazz.getSuperclass();
	String clazzName = clazz.getSimpleName();
	String superName = superclazz.getSimpleName();
	if (!superclazz.getName().equals("java.lang.Object")) {
		/* Windows exception - cannot call get/set function of super class in this case */
		if (!(clazzName.equals(superName + "A") || clazzName.equals(superName + "W"))) {
			output("\tset");
			output(superName);
			output("Fields(env, lpObject, (");
			output(superName);
			outputln(" *)lpStruct);");
		} else {
			generateSetFields(superclazz);
		}
	}
	JNIField[] fields = clazz.getDeclaredFields();
	for (int i = 0; i < fields.length; i++) {
		JNIField field = fields[i];
		if (ignoreField(field)) continue;
		String exclude = field.getExclude();
		if (exclude.length() != 0) {
			outputln(exclude);
		}
		boolean noWinCE = field.getFlag(FLAG_NO_WINCE);
		if (noWinCE) {
			outputln("#ifndef _WIN32_WCE");
		}
		JNIType type = field.getType(), type64 = field.getType64();
		String typeName = type.getSimpleName();
		String accessor = field.getAccessor();
		if (accessor == null || accessor.length() == 0) accessor = field.getName();
		boolean isCPP = getCPP();
		if (type.isPrimitive()) {
			if (isCPP) {
				output("\tenv->Set");
			} else {
				output("\t(*env)->Set");
			}
			output(type.getTypeSignature1(!type.equals(type64)));
			if (isCPP) {
				output("Field(lpObject, ");
			} else {
				output("Field(env, lpObject, ");
			}
			output(field.getDeclaringClass().getSimpleName());
			output("Fc.");
			output(field.getName());
			output(", (");
			output(type.getTypeSignature2(!type.equals(type64)));
			output(")lpStruct->");
			output(accessor);
			output(");");
		} else if (type.isArray()) {
			JNIType componentType = type.getComponentType(), componentType64 = type64.getComponentType();
			if (componentType.isPrimitive()) {
				outputln("\t{");
				output("\t");				
				output(type.getTypeSignature2(!type.equals(type64)));
				output(" lpObject1 = (");
				output(type.getTypeSignature2(!type.equals(type64)));
				if (isCPP) {
					output(")env->GetObjectField(lpObject, ");
				} else {
					output(")(*env)->GetObjectField(env, lpObject, ");
				}
				output(field.getDeclaringClass().getSimpleName());
				output("Fc.");
				output(field.getName());
				outputln(");");
				if (isCPP) {
					output("\tenv->Set");
				} else {
					output("\t(*env)->Set");
				}
				output(componentType.getTypeSignature1(!componentType.equals(componentType64)));
				if (isCPP) {
					output("ArrayRegion(lpObject1, 0, sizeof(lpStruct->");
				} else {
					output("ArrayRegion(env, lpObject1, 0, sizeof(lpStruct->");
				}
				output(accessor);
				output(")");
				if (!componentType.isType("byte")) {
					output(" / sizeof(");
					output(componentType.getTypeSignature2(!componentType.equals(componentType64)));
					output(")");
				}
				output(", (");
				output(type.getTypeSignature4(!type.equals(type64), false));				
				output(")");
				if (field.getFlag(FLAG_STRUCT)) {
					output("&");
				}
				output("lpStruct->");
				output(accessor);
				outputln(");");
				output("\t}");
			} else {
				throw new Error("not done");
			}
		} else {
			outputln("\t{");
			output("\tjobject lpObject1 = (*env)->GetObjectField(env, lpObject, ");
			output(field.getDeclaringClass().getSimpleName());
			output("Fc.");
			output(field.getName());
			outputln(");");
			output("\tif (lpObject1 != NULL) set");
			output(typeName);
			output("Fields(env, lpObject1, &lpStruct->");
			output(accessor);
			outputln(");");
			output("\t}");
		}
		outputln();
		if (noWinCE) {
			outputln("#endif");
		}
		if (exclude.length() != 0) {
			outputln("#endif");
		}
	}
}

void generateSetFunction(JNIClass clazz) {
	String clazzName = clazz.getSimpleName();
	output("void set");
	output(clazzName);
	output("Fields(JNIEnv *env, jobject lpObject, ");
	if (clazz.getFlag(Flags.FLAG_STRUCT)) {
		output("struct ");
	}
	output(clazzName);
	outputln(" *lpStruct)");
	outputln("{");
	output("\tif (!");
	output(clazzName);
	output("Fc.cached) cache");
	output(clazzName);
	outputln("Fields(env, lpObject);");
	generateSetFields(clazz);
	outputln("}");
}

void generateFunctions(JNIClass clazz) {
	generateCacheFunction(clazz);
	outputln();
	generateGetFunction(clazz);
	outputln();
	generateSetFunction(clazz);
}

boolean ignoreField(JNIField field) {
	int mods = field.getModifiers();
	return
		((mods & Modifier.PUBLIC) == 0) ||
		((mods & Modifier.FINAL) != 0) ||
		((mods & Modifier.STATIC) != 0);
}

}
