[% import "../thrift-helper-functions.eol";

operation String makeJavaComment(padding : String) : String {
	return self.makeComment("/**"+EOL(), " * ", " */"+EOL(), padding);
}

operation Field isPrimitive() : Boolean {
	return self.fieldType.isPrimitive();
}

@cached
operation FieldType isPrimitive() : Boolean {
	return self.javaType().isJavaPrimitive();
}

operation String javaString() : String {
	return self.escapedString();
}

@cached
operation String isBaseJava() : Boolean {
	return self.matches("ByteBuffer") or self.convertToPrimitive().isJavaPrimitive();
}

@cached
operation String convertToPrimitive() : String {
	if (self.matches("String") or self.matches("ByteBuffer") or self.isJavaContainer()) {
		return self;
	}
	switch (self) {
		case "Integer": return "int";
		case "Character": return "char";
		default: return self.firstToLowerCase();
	}
}

@cached
operation String isJavaType() : Boolean {
	return
		self.isJavaPrimitive() or
		self.isJavaContainer() or
		self == "Byte" or
		self == "ByteBuffer" or
		self == "Boolean" or
		self == "Integer" or
		self == "Double" or
		self == "Long" or
		self == "Short" or
		self == "Character" or
		self.firstToLowerCase() == "void";
}

operation String isJavaContainer() : Boolean {
	return "<".isSubstringOf(self) and (
		self.startsWith("Array") or
		self.startsWith("List") or
		self.startsWith("Map") or
		self.startsWith("Set") or
		self.startsWith("HashMap") or
		self.startsWith("TreeMap") or
		self.startsWith("HashSet") or
		self.startsWith("TreeSet"));
}

@cached
operation String isJavaPrimitive() : Boolean {
	return
		self == "byte" or
		self == "boolean" or
		self == "int" or
		self == "double" or
		self == "long" or
		self == "short" or
		self == "char";
}

@cached
operation String javaToThriftType() : String {
	return self.toLowerCase()
		.replace("bytebuffer", "binary")
		.replace("boolean", "bool")
		.replace("int", "i32")
		.replace("integer", "i32")
		.replace("long", "i64")
		.replace("short", "i16");
}

operation String resolveJavaType(generic : Boolean) : String {
	var javaType : String = self
		.replace("string", "String")
		.replace("map", "Map")
		.replace("list", "List")
		.replace("set", "Set")
		.replace("binary", "ByteBuffer")
		.replace("slist", "String")
		.replace("i8", "byte");

	if (generic) {
		javaType = javaType
			.replace("bool", "Boolean")
			.replace("i32", "Integer")
			.replace("double", "Double")
			.replace("i64", "Long")
			.replace("byte", "Byte")
			.replace("i16", "Short")
			.replace("void", "Void");
	}
	else {
		javaType = javaType
			.replace("bool", "boolean")
			.replace("i32", "int")
			.replace("i64", "long")
			.replace("i16", "short");
	}
	return javaType;
}

operation String resolveJavaType() : String {
	return self.resolveJavaType("<".isSubstringOf(self));
}

@cached
operation Const javaType() : String {
	if (self.fieldType.isUndefined()) return "";
	return self.fieldType.javaType();
}

@cached
operation Field javaType() : String {
	if (self.fieldType.isUndefined()) return "";
	return self.fieldType.javaType();
}

operation Field javaType(generic : Boolean) : String {
	if (self.fieldType.isUndefined()) return "";
	return self.fieldType.javaType(generic);
}

operation FieldType javaType(generic : Boolean) : String {
	if (generic) {
		if (self.~genericJavaType.isUndefined()) {
			self.~genericJavaType = self.thriftType().resolveJavaType(true);
		}
		return self.~genericJavaType;
	}
	if (self.~normalJavaType.isUndefined()) {
		self.~normalJavaType = self.thriftType().resolveJavaType(false);
	}
	return self.~normalJavaType;
}

@cached
operation FieldType javaType() : String {
	return self.javaType(self.isContainer());
}

@cached
operation Field concreteJavaType() : String {
	if (self.fieldType.isUndefined()) return "";
	return self.fieldType.concreteJavaType();
}

operation FieldType concreteJavaType() : String {
	if (self.~concreteJavaType.isUndefined()) {
		self.~concreteJavaType = self.javaType().concreteJavaType();
	}
	return self.~concreteJavaType;
}

@cached
operation String concreteJavaType() : String {
	if (self.startsWith("List"))
		return "Array"+self;
	else if (self.startsWith("Set") or self.startsWith("Map"))
		return "Hash"+self;
	return self;
}

operation Field getTtype() : String {
	assertTrue(self.fieldType.isDefined());
	return self.fieldType.getTtype();
}

@cached
operation FieldType getTtype() : String {
	return self.getTtype(true);
}

operation FieldType getTtype(changeEnumToI32 : Boolean) : String {
	var typename : String = self.getTypeName();
	return "org.apache.thrift.protocol.TType."+typename.changeIf(changeEnumToI32 and self.isEnum(), "I32");
}

@cached
operation Function getType() : String {
	return self.getType(false);
}

operation Function getType(generic : Boolean) : String {
	if (self.isVoid()) {
		return generic.ternary("Void", "void");
	}
	if (self.funcType.isDefined() and self.funcType.fieldType.isDefined()) {
		return self.funcType.fieldType.javaType(generic);
	}
	return "";
}

operation Function isPrimitive() : Boolean {
	if (self.~isPrimitive.isUndefined()) {
		self.~isPrimitive = self.funcType.fieldType.isDefined() and self.funcType.fieldType.isPrimitive();
	}
	return self.~isPrimitive;
}

operation Function getSignature(exception : String) : String {
	if (not self.~javaSignature.isDefined()) {
		self.~javaSignature = self.getType()+' '+self.identifier+'('+self.getArgs(true)+')';
	}
	if (exception.isDefined() and exception.length() > 0) {
		return self.~javaSignature+" throws "+exception;
	}
	return self.~javaSignature;
}

operation Function getArgs(includeTypes : Boolean) : String {
	return self.getArgs(includeTypes, false);
}

operation Function getArgs(includeTypes : Boolean, includeContinuation : Boolean) : String {
	return self.getArgs(includeTypes, "", "".changeIf(includeContinuation, ", "));
}

operation Function getArgs(includeTypes : Boolean, prefixText : String, continuation : String) : String {
	var argstr : String = "";
	for (arg in self.args) {
		if (includeTypes and arg.fieldType.isDefined()) {
			argstr += arg.fieldType.javaType()+' ';
		}
		argstr += prefixText+arg.identifier+", ";
	}
	if (argstr.endsWith(", ")) {
		argstr = argstr.substring(0, argstr.length()-2);
	}
	if (self.args.size() > 0) {
		argstr += continuation;
	}
	return argstr;
}

@cached
operation Function getExceptions() : String {
	var excsig : String = "";
	for (xception in self.exceptions) {
		excsig += xception.fieldType.identifier+", ";
	}
	return excsig+"org.apache.thrift.TException";
}

operation Field getDeclaration() : String {
	return self.getDeclaration("", false, "");
}

operation Field getDeclaration(visibility : String, reqComment : Boolean) : String {
	return self.getDeclaration(visibility, reqComment, ';');
}

operation Field getDeclaration(visibility : String, reqComment : Boolean, sep : String) : String {
	var decStr : String = "";
	if (visibility.isDefined() and visibility.length() > 0) {
		decStr = visibility+' ';
	}
	if (self.fieldType.isDefined()) {
		decStr += self.fieldType.javaType()+' '+self.identifier+sep;
	}
	if (reqComment) {
		var requiredness : String = "required";
		if (self.fieldReq.isDefined() and self.fieldReq.literal == "optional")
			requiredness = "optional";
		decStr += " // "+requiredness;
	}
	return decStr;
}

operation Function printComment(padding : String) {
	if (self.comment.isDefined()) {
		var contents : String = self.comment.getCommentContents();
		for (arg in self.args) {
			contents += "\n@param "+arg.identifier;
			if (arg.comment.isDefined()) {
				contents += ' '+arg.getRawComment();
			}
		}
		out.print(contents.makeJavaComment(padding));
	}
}

operation Field printComment(padding : String) {
	if (self.isEnum()) {
		out.print((self.comment+"\n@see "+self.thriftType()).makeJavaComment(padding));
	}
	if (self.comment.isDefined()) {
		out.print(self.getRawComment().makeJavaComment(padding));
	}
}

operation FieldType printMetaData(basePadding : String) {
	var padding : String = basePadding+"    ";
	var ttype : String = self.getTtype(false);
	var typeName = self.getTypeName().toLowerCase.firstToUpperCase();
	var tmeta : String = "new org.apache.thrift.meta_data.";
	if (self.isBase()) {
		tmeta += "FieldValue";
	}
	else {
		tmeta += typeName;
	}
	tmeta += "MetaData("+ttype;
	if (not self.isBase()) {
		tmeta += ", ";
	}
	out.print(padding+tmeta);
	
	if (self.isEnum() or self.isStruct()) {
		out.print(self.identifier+".class");
	}
	else if (self.isBase()) {
		if (self.~typedef.isDefined() or self.isBinary()) {
			out.print(padding+", ");
			if (self.~typedef.isDefined()) {
				out.print('"'+self.~typedef+'"');
			}
			else {
				out.print("true");
			}
		}
	}
	else if (self.defType.isDefined()) {
		out.println();
		var container = self.defType.container;
		if (container.isDefined()) {
			if (container.keyword == "map") {
				container.keyType.printMetaData(padding);
				out.println(", ");
				container.valType.printMetaData(padding);
			}
			else {
				container.fieldType.printMetaData(padding);
			}
		}
		else if (self.defType.base.isDefined()) {
			tmeta = tmeta.replace(typeName, "FieldValue").replace(typeName, self.defType.base.literal.toUpperCase());
			out.print(padding+tmeta);
		}
	}
	out.print(')');
}

operation printDeepCopyContainer(padding : String, innerType : String, iteratorName : String, resultName : String, afterFor : String) {
	out.print(padding+innerType+' '+resultName+" = new "+innerType.concreteJavaType()+'('+iteratorName);
	if (innerType.hasNesting()) {
		var nextInner : String = innerType.getInnerType();
		var nextIterName : String = iteratorName.split("\\.").first()+"_element";
		var nextResName : String = resultName+"_copy";
		var nextPadding : String = padding+"  ";
		out.println(".size());");
		out.print(padding+"for (");
		if (innerType.startsWith("Map")) {
			var nextKey : String = innerType.getMapKey();
			var nextValue : String = innerType.getMapValue();
			out.println("Map.Entry<"+nextInner.spaceBetweenMap()+"> "+nextIterName+" : "+iteratorName+".entrySet()) {");
			out.println();
			out.println(nextPadding+nextKey+' '+nextIterName+"_key = "+nextIterName+".getKey();");
			out.println(nextPadding+nextValue+' '+nextIterName+"_value = "+nextIterName+".getValue();");
			out.println();
			printDeepCopyContainer(nextPadding, nextKey, nextIterName+"_key", nextResName+"_key", null);
			out.println();
			printDeepCopyContainer(nextPadding, nextValue, nextIterName+"_value", nextResName+"_value", null);
			out.println();
			out.println(nextPadding+resultName+".put("+nextResName+"_key, "+nextResName+"_value);");
		}
		else {
			out.println(nextInner+' '+nextIterName+" : "+iteratorName+") {");
			if (nextInner.hasNesting()) {
				printDeepCopyContainer(nextPadding, nextInner, nextIterName, nextResName, nextPadding+resultName+".add("+nextResName+");");	
			}
			else {
				var addArg : String = nextIterName;
				if (nextInner.isType("ByteBuffer")) {
					out.println(nextPadding+"ByteBuffer temp_binary_element = org.apache.thrift.TBaseHelper.copyBinary("+nextIter+");");
					addArg += "temp_binary_element";
				}
				else if (not nextInner.isJavaType()) {
					addArg = "new "+nextInner+'('+addArg+')';
				}
				addArg += ");";
				out.println(nextPadding+resultName+".add("+addArg);
			}
		}
		out.println(padding+'}');
		if (afterFor.isDefined()) {
			out.println(afterFor);
		}
	}
	else {
		out.println(");");
	}
}

operation Field printDeepCopy(padding : String) {
	var otherName : String = "other."+self.identifier;
	if (not self.isPrimitive()) {
    	out.println(padding+"if (other.isSet"+self.~accessorName+"()) {");
    	padding += "  ";
    }
    if (self.isContainer()) {
    	var resultName : String = "__this__"+self.identifier;
    	var javaType : String = self.javaType();
    	if (self.fieldType.nestedTypeIsBase()) {
    		out.println(padding+javaType+' '+resultName+" = new "+javaType.concreteJavaType()+'('+otherName+");");
    	}
    	else {
	    	printDeepCopyContainer(padding, javaType, otherName, resultName, null);
	    }
	    otherName = "__this__"+self.identifier;
    }
    //For some reason, this logic is not executed by the Thrift Java generator even though it's in the source code!
    else if (self.fieldType.isBinary()) {
	    otherName = "org.apache.thrift.TBaseHelper.copyBinary("+otherName+')';
	}
	else if (self.fieldType.isStruct()) {
	    otherName = "new "+self.fieldType.identifier+'('+otherName+')';
	}
	out.println(padding+"this."+self.identifier+" = "+otherName+';');
    if (not self.isPrimitive()) {
    	padding = padding.substring(2);
    	out.println(padding+'}');
    }
}

operation Field printSerialize(prefix : String, hasMetadata : Boolean, padding : String) {
	self.fieldType.printSerialize(prefix, self.identifier, hasMetadata, padding);
}

operation FieldType printSerialize(prefix : String, identifier : String, hasMetadata : Boolean, padding : String) {
	var thriftType : String = self.thriftType();
	var javaType = self.javaType();
	var name : String = prefix+identifier;
	if (self.isStruct() or self.isException()) {
		out.println(padding+name+".write(oprot);");
	}
	else if (self.isEnum()) {
		out.println(padding+"oprot.writeI32("+name+".getValue());");
	}
	else if (self.isContainer()) {
		var iterName : String = "_iter".iterNum();
		var container = self.defType.container;
		var containerType : String = container.keyword.firstToUpperCase();
		out.println(padding+'{');
		padding += "  ";
		out.print(padding+"oprot.write");
		if (hasMetadata) {
			out.print(containerType+"Begin(new org.apache.thrift.protocol.T"+containerType+'(');
			if (self.isMap()) {
				var key = container.keyType;
				var value = container.valType;
				out.print(key.getTtype()+", "+value.getTtype());
			}
			else {
				out.print(container.fieldType.getTtype());
			}
			out.print(", ");
		}
		else {
			out.print("I32(");
		}
		out.println(name+".size())"+("".changeIf(hasMetadata, ")"))+';');
		out.print(padding+"for (");
		if (self.isMap() and container.keyType.isDefined() and container.valType.isDefined()) {
			out.print("Map.Entry<"+container.keyType.javaType()+", "+container.valType.javaType()+"> "+iterName+" : "+name+".entrySet()");
		}
		else if (container.fieldType.isDefined()) {
			out.print(container.fieldType.javaType()+' '+iterName+" : "+name);
		}
		out.println(')');
		
		out.println(padding+'{');
		if (self.isMap()) {
			container.keyType.printSerialize("", iterName+".getKey()", hasMetadata, padding+"  ");
			container.valType.printSerialize("", iterName+".getValue()", hasMetadata, padding+"  ");
		}
		else {
			container.fieldType.printSerialize("", iterName, hasMetadata, padding+"  ");
		}
		out.println(padding+'}');
		
		if (hasMetadata) {
			out.println(padding+"oprot.write"+containerType+"End();");
		}
		padding = padding.substring(2);
		out.println(padding+'}');
	}
	else if (self.isBase()) {
		out.println(padding+"oprot.write"+thriftType.firstToUpperCase()+'('+name+");");
	}
}

operation Field printDeserialize(prefix : String, hasMetadata : Boolean, padding : String) {
	self.fieldType.printDeserialize(prefix, self.identifier, hasMetadata, padding);
}

operation FieldType printDeserialize(prefix : String, identifier : String, hasMetadata : Boolean, padding : String) {
	var thriftType : String = self.thriftType();
	var javaType = self.javaType();
	var name : String = prefix+identifier;
	if (self.isStruct() or self.isException()) {
		out.println(padding+name+" = new "+self.identifier+"();");
		out.println(padding+name+".read(iprot);");
	}
	else if (self.isEnum()) {
		out.println(padding+name+" = "+self.identifier+".findByValue(iprot.readI32());");
	}
	else if (self.isContainer()) {
		var isMap = self.isMap();
		var container = self.defType.container;
		var containerType : String = container.keyword.firstToUpperCase();
		var objName : String = ("_"+container.keyword).iterNum();
		out.println(padding+'{');
		padding += "  ";
		out.print(padding+"org.apache.thrift.protocol.T"+containerType+' '+objName+" = ");
		if (hasMetadata) {
			out.println("iprot.read"+containerType+"Begin();");
		}
		else {
			out.print("new org.apache.thrift.protocol.T"+containerType+'(');
			if (isMap) {
				out.print(container.keyType.getTtype()+", "+container.valType.getTtype());
			}
			else {
				out.print(container.fieldType.getTtype());
			}
			out.println(", iprot.readI32());");
		}
		out.println(padding+name+" = new "+self.concreteJavaType()+'('+"2*".changeIf(self.isList(), "")+objName+".size);");
		
		var i : String;
		var colElem : String;
		var keyElem : String;
		var valElem : String;
		if (isMap and container.keyType.isDefined() and container.valType.isDefined()) {
			keyElem = "_key".iterNum();
			valElem = "_val".iterNum();
			out.println(padding+container.keyType.javaType()+' '+keyElem+';');
			out.println(padding+container.valType.javaType()+' '+valElem+';');
		}
		else if (container.fieldType.isDefined()) {
			colElem = "_elem".iterNum();
			out.println(padding+container.fieldType.javaType()+' '+colElem+';');
		}
		i = "_i".iterNum();
		out.println(padding+"for (int "+i+" = 0; "+i+" < "+objName+".size; ++"+i+')');
		out.println(padding+'{');
		padding += "  ";
		if (isMap) {
			container.keyType.printDeserialize("", keyElem, hasMetadata, padding);
			container.valType.printDeserialize("", valElem, hasMetadata, padding);
			out.println(padding+name+".put("+keyElem+", "+valElem+");");
		}
		else if (container.fieldType.isDefined()) {
			container.fieldType.printDeserialize("", colElem, hasMetadata, padding);
			out.println(padding+name+".add("+colElem+");");
		}
		padding = padding.substring(2);
		out.println(padding+'}');
		
		if (hasMetadata) {
			out.println(padding+"iprot.read"+containerType+"End();");
		}
		padding = padding.substring(2);
		out.println(padding+'}');
	}
	else if (self.isBase()) {
		out.println(padding+name+" = iprot.read"+thriftType.firstToUpperCase()+"();");
	}
}

operation printMetadataMap(fields, identifier : String) {%]
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    [% for (field in fields) {%]
    tmpMap.put(_Fields.[%=field.~capsIdentifier%], new org.apache.thrift.meta_data.FieldMetaData("[%=field.identifier%]", org.apache.thrift.TFieldRequirementType.[%=field.getRequirement()%], 
	[%  field.fieldType.printMetaData("    ");
		out.println("));");
    }%]
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap([%=identifier%].class, metaDataMap);
  }
[%}

operation printFieldsEnum(fields) {%]
  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    [% if (fields.size() > 0)
    	for (i : Integer in Sequence{0..fields.size()-1}) {
    		var field : Field = fields.at(i);
    		field.printComment("    "); %]
    [%=field.~capsIdentifier%]((short)[%=field.fieldID%], "[%=field.identifier%]")[%=",".changeIf(i == fields.size()-1, ";")%]
    [%}%]

    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

    static {
      for (_Fields field : EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
      [% for (field in fields) {%]
        case [%=field.fieldID%]: // [%=field.~capsIdentifier%]
          return [%=field.~capsIdentifier%];
      [%}%]
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

    _Fields(short thriftId, String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }
[%}

operation printTFieldDeclarations(fields, padding : String) {
	for (field in fields) {
		out.println(padding+"private static final org.apache.thrift.protocol.TField "+field.identifier.camelToUnderscore()+"_FIELD_DESC = new org.apache.thrift.protocol.TField(\""+field.identifier+"\", "+field.getTtype()+", (short)"+field.fieldID+");");
	}
}

operation printFileHead(author : String, pkg, comment : String) {
	printFileHead(author, pkg, comment, null);
}

operation printFileHead(author : String, pkg, comment : String, date : String) {
	printHeaderMessage(author); %]
[% printPackage(pkg); %]
[% printImports(); %]

[% printSuppressWarnings(); %]
[% if (comment.isDefined() and comment.length() > 3)
	out.println(comment); %]
[% 	if (date.isDefined() and date.length() > 1) {
		printDateAuthor(date, author);
	}
}

operation printHeaderMessage(author : String) {%]
/**
 * Autogenerated by [%=author%]
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
[%}

operation printPackage(pkg) {
	if (pkg.isDefined()) {%]
[%="package "+pkg%];

[%}
}

operation printImports() {
%]import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
[%}

operation printDateAuthor(date : String, author : String) {%]
@Generated(value = "Autogenerated by [%=author%]", date = "[%=date%]")
[%}

operation printSuppressWarnings() {%]
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
[%}

%]