/*
 * Copyright (c) 2021
 * NDE Netzdesign und -entwicklung AG, Hamburg, Germany
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program (see the file LICENSE.txt for more
 * details); if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 */

package org.acplt.oncrpc.apps.jrpcgen;

/**
 * The type mapping specifies methods supplying type identification and
 * generation of type specific code snippets. The type mapping is intended
 * to reduce complexity writing code generation sequences by passing
 * repsonsibility for type specifics to the type mapping. This allows
 * more or less type independent and more readable code at a higher level
 * of code generation statements. 
 * 
 * @author Harald Wirths {@literal <hwirths@nde.ag>}
 *
 */
public interface JrpcgenTypeMapping {
	
	/**
	 * Returns whether the mapped type is {@code void}.
	 * 
	 * @return {@code true} in case the mapped type is
	 *         {@code void}, {@code false} otherwise.
	 */
	boolean isVoid();
	
	/**
	 * Returns whether the mapped type belongs to the family of
	 * the base types. Base types are:
	 * <ul>
	 * <li>{@code void}</li>
	 * <li>{@code boolean}</li>
	 * <li>{@code byte}</li>
	 * <li>{@code short}</li>
	 * <li>{@code int}</li>
	 * <li>{@code long}</li>
	 * <li>{@code float}</li>
	 * <li>{@code double}</li>
	 * <li>{@code String}</li>
	 * <li>{@code opaque}</li>
	 * </ul>
	 * For more details on base types see {@link JrpgenBaseType}.
	 * 
	 * @return {@code true} in case the mapped type belongs to the family
	 *         of base types, {@code false} otherwise.
	 */
	boolean isBaseType();
	
	/**
	 * Returns whether the mapped type is {@code boolean}.
	 * 
	 * @return {@code true} in case the mapped type is {@code boolean},
	 *         {@code false} otherwise.
	 */
	boolean isBooleanType();
	
	/**
	 * Returns whether the mapped type is {@code String}.
	 * 
	 * @return {@code true} in case the mapped type is {@code String},
	 *         {@code false} otherwise.
	 */
	boolean isStringType();
	
	/**
	 * Returns whether the mapped type is {@code opaque}.
	 * 
	 * @return {@code true} in case the mapped type is {@code opaque},
	 *         {@code false} otherwise.
	 */
	boolean isOpaqueType();

	/**
	 * Returns the definition name of the mapped type in the x-file.
	 * 
	 * @return The definition name of the mapped type.
	 */
	String getDefinitionName();
	
	/**
	 * Returns the Java name of the mapped type.
	 * 
	 * @return The Java name of the mapped type.
	 */
	String getJavaName();
	
	/**
	 * Returns the name of the Java class belonging to the mapped type.
	 * The returned value will be equal to the Java name of the
	 * mapped type, if the mapped type is a Java class.
	 * For types mapped to Java primitives like {@code int},
	 * this method is expected to return the name of the wrapper class
	 * to the Java primitive.
	 * 
	 * @return The name of the Java class representing the mapped type.
	 */
	String getJavaClass();
	
	/**
	 * Returns the name of the XDR class providing the coding methods
	 * of the mapped type, in detail the class implementing the interface
	 * {@link XdrAble} for the mapped type. For base types the returned
	 * value will be one of the provided XDR classes of the ONC/RPC runtime
	 * library. For enumerations the returned value depends on the given
	 * value to the flag <em>noEnum</em>. However, the returned value identifies
	 * an XDR class provided by the ONC/RPC runtime library, in detail either
	 * {@link XdrInt} with flag <em>noEnum</em> set to {@code true} or
	 * {@link XdrEnum} with flag <em>noEnum</em> set to {@code false}.
	 * For other complex types the returned value will be equal to the Java name
	 * and Java class, respectively.
	 * 
	 * @return The name of the XDR class implementing the coding methods for
	 *         the mapped type.
	 */
	String getXdrClass();
	
	/**
	 * A constructor call based on the XDR class of the mapped type is written to
	 * the passed Java file. Dependent on the passed parameter the constructor
	 * call becomes a call without a parameter or one parameter. 
	 * 
	 * @param javaFile The Java file, where the XDR constructor call is going to be placed. 
	 * @param parameter {@code null} to generate a default constructor call, a parameter
	 *        name to generate a constructor call with one parameter.
	 */
	void writeXdrConstructorCall(JrpcgenJavaFile javaFile, String parameter);
	
	/**
	 * A constructor call based on the XDR class of the mapped type is written to
	 * the passed Java file. The parameter expression is intended to write an expression,
	 * which evaluates to a parameter to the constructor call.
	 * 
	 * @param javaFile The Java file, where the constuctor call is going to be placed. 
	 * @param parameterExpression An expression to be called with the passed Java file,
	 *        when the expression is going to be placed in the Java file.
	 */
	void writeXdrConstructorCall(JrpcgenJavaFile javaFile, JrpcgenJavaFile.Expression parameterExpression);
	
	/**
	 * Writes a conversion statement to the passed Java file changing the Java representation
	 * of a variable to the corresponding XDR representation, in order to enable XDR encoding
	 * operations on the referenced variable.
	 * 
	 * @param javaFile The java file, where the converison statement is going to be placed.
	 * @param variable The name of a variable in Java representation.
	 */
	void writeJavaToXdr(JrpcgenJavaFile javaFile, String variable);
	
	/**
	 * Writes a conversion statement to the passed Java file changing the Java representation
	 * resulting from the passed expression to the corresponding XDR representation, in order
	 * to enable XDR encoding operations on the result of the passed expression.
	 * 
	 * @param javaFile The Java file, where the conversion statement is going to be placed.
	 * @param expression An expression to be called with the passed Java file, when the
	 *        expression is going to be placed in the Java file.
	 */
	void writeJavaToXdr(JrpcgenJavaFile javaFile, JrpcgenJavaFile.Expression expression);
	
	/**
	 * Writes a conversion statement to the passed Java file changing the XDR representation
	 * of a variable to the corresponding Java representation, which takes place after
	 * XDR decoding operations.
	 * 
	 * @param javaFile The Java file, where the conversion statement is going to be placed.
	 * @param variable The name of a variable in XDR representation. 
	 */
	void writeXdrToJava(JrpcgenJavaFile javaFile, String variable);
	
	/**
	 * Writes an XDR encoding call to the passed Java file using the passed name of an
	 * XDR encoding stream and the passed name of a variable. The referenced variable is
	 * expected to represent a value of the mapped type.
	 * 
	 * @param javaFile The Java file, where the XDR encoding call is going to be placed. 
	 * @param xdrStream The name of the XDR encoding stream instance to be used in the statement.
	 * @param variable The name of the variable to be used in the statement.
	 */
	void writeXdrEncodingCall(JrpcgenJavaFile javaFile, String xdrStream, String variable);
	
	/**
	 * Writes an XDR encoding call to the passed Java file using the passed name of an
	 * XDR encoding stream and the result of the passed experssion. The result of the passed
	 * expression is expected to represent a value of the mapped type. 
	 * 
	 * @param javaFile The Java file, where the XDR encoding code is going to be placed.
	 * @param xdrStream The name of the XDR encoding stream instance to be used in the statement.
	 * @param expression An expression to be called with the passed Java file, when the
	 *        expression is going to be placed in the Java file.
	 */
	void writeXdrEncodingCall(JrpcgenJavaFile javaFile, String xdrStream, JrpcgenJavaFile.Expression expression);
	
	/**
	 * Writes an XDR encoding call for a fixed vector to the passed Java file using the passed
	 * name of an XDR encoding stream, the passed name of a variable and the passed size.
	 * The rerferenced variable is expected to repesent an array of the mapped type.
	 * 
	 * @param javaFile The Java file, where the XDR encoding call is going to be placed.
	 * @param xdrStream The name of the XDR encoding stream instance to be used in the statement.
	 * @param variable The name of the variable to be used in the statement. 
	 * @param size A string specifying the size of the fixed vector.
	 */
	void writeXdrFixedVectorEncodingCall(JrpcgenJavaFile javaFile, String xdrStream, String variable, String size);
	
	/**
	 * Writes an XDR encoding call for a dynamic vector to the passed Java file using the passed
	 * name of an XDR encoding stream and the passed name of a variable. The referenced variable
	 * is expected to represent an array of the mapped type.
	 * 
	 * @param javaFile The Java file, where the XDR encoding call is going to be placed.
	 * @param xdrStream The name of the XDR encoding stream instance to be used in the statement.
	 * @param variable The name of the variable to be used in the statement.
	 */
	void writeXdrDynamicVectorEncodingCall(JrpcgenJavaFile javaFile, String xdrStream, String variable);
	
	/**
	 * Writes an XDR decoding call to the passed Java file using the passed name of an XDR decoding
	 * stream.
	 * 
	 * @param javaFile The Java file, where the XDR decoding call is going to be placed.
	 * @param xdrStream The name of the XDR decoding stream instance to be used in the statement.
	 */
	void writeXdrDecodingCall(JrpcgenJavaFile javaFile, String xdrStream);
	
	/**
	 * Writes an XDR decoding call for a fixed vector to the passed Java file using the passed name
	 * of an XDR decoding stream and the passed size.
	 * 
	 * @param javaFile The Java file, where the XDR decoding call is going to be placed.
	 * @param xdrStream The name of the XDR decoding stream instance to be used in the statement.
	 * @param size A string specifying the size of the fixed vector. 
	 */
	void writeXdrFixedVectorDecodingCall(JrpcgenJavaFile javaFile, String xdrStream, String size);
	
	/**
	 * Writes an XDR decoding call for a dynamic vector to the passed Java file using the passed
	 * name of an XDR decoding stream.
	 * 
	 * @param javaFile The Java file, where the XDR decoding call is going to be placed.
	 * @param xdrStream The name of the XDR decoding stream instance to be used in the statement.
	 */
	void writeXdrDynamicVectorDecodingCall(JrpcgenJavaFile javaFile, String xdrStream);
	
	/**
	 * Writes an equals expression to the passed Java file using the passed names of a left hand side
	 * and a right hand side variable. The negate parameter controls whether the statement evaluates
	 * to {@code true} on equality or on inequality.
	 * 
	 * @param javaFile The Java file, where the equality expression is going to be placed.
	 * @param variableLeft The name of the variable to be used as the left hand side in the statement.
	 * @param variableRight The name of the variable to be used as the right hand side in the statement.
	 * @param negate {@code false} to let the resulting statement return {@code true} on equality,
	 *        {@code true} to let the resulting statement return {@code true} on inequality.
	 */
	void writeEqualsExpression(JrpcgenJavaFile javaFile, String variableLeft, String variableRight, boolean negate);
	
}