/**
 *
 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either 
 * version 2.1 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public 
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 * 
 **/
package lucee.runtime.exp;

import lucee.runtime.type.FunctionArgument;
import lucee.runtime.type.UDF;
import lucee.runtime.type.util.Type;

public class UDFCasterException extends CasterException {

	private static final long serialVersionUID = 4863042711433241644L;

	public UDFCasterException(UDF udf, FunctionArgument arg, Object value, int index) {
		super(createMessage(udf, arg, value, index), createDetail(udf));
	}

	public UDFCasterException(UDF udf, String returnType, Object value) {
		super(createMessage(udf, returnType, value), createDetail(udf));
	}

	private static String createMessage(UDF udf, String type, Object value) {
		String detail;
		if (value instanceof String) return "can't cast String [" + CasterException.crop(value) + "] to a value of type [" + type + "]";
		else if (value != null) detail = "can't cast Object type [" + Type.getName(value) + "] to a value of type [" + type + "]";
		else detail = "can't cast null value to value of type [" + type + "]";
		return "the function " + udf.getFunctionName() + " has an invalid return value , " + detail;

	}

	private static String createMessage(UDF udf, FunctionArgument arg, Object value, int index) {
		String detail;
		if (value instanceof String) detail = "can't cast String [" + CasterException.crop(value) + "] to a value of type [" + arg.getTypeAsString() + "]";
		else if (value != null) detail = "can't cast Object type [" + Type.getName(value) + "] to a value of type [" + arg.getTypeAsString() + "]";
		else detail = "can't cast Null value to value of type [" + arg.getTypeAsString() + "]";

		return "invalid call of the function " + udf.getFunctionName() + ", " + posToString(index) + " Argument (" + arg.getName() + ") is of invalid type, " + detail;
	}

	private static String createDetail(UDF udf) {
		return "the function is located at [" + udf.getSource() + "]";
	}

	private static String posToString(int index) {
		if (index == 1) return "first";
		if (index == 2) return "second";
		return index + "th";
	}
}
@@ -1450,20 +1450,21 @@
 return %22
-can'
+Canno
 t cast S
@@ -1571,36 +1571,37 @@
 null) detail = %22
-can'
+Canno
 t cast Object ty
@@ -1682,28 +1682,29 @@
 e detail = %22
-can'
+Canno
 t cast null 
@@ -1745,33 +1745,33 @@
  %22%5D%22;%0A%09%09return %22
-t
+T
 he function %22 + 
@@ -1758,32 +1758,33 @@
 n %22The function 
+%5B
 %22 + udf.getFunct
@@ -1796,16 +1796,17 @@
 me() + %22
+%5D
  has an 
@@ -1828,16 +1828,17 @@
 value , 
+%5B
 %22 + deta
@@ -1839,16 +1839,22 @@
 + detail
+ + %22%5D%22
 ;%0A%0A%09%7D%0A%0A%09
@@ -2001,28 +2001,29 @@
 ) detail = %22
-can'
+Canno
 t cast Strin
@@ -2147,28 +2147,29 @@
 ) detail = %22
-can'
+Canno
 t cast Objec
@@ -2275,17 +2275,17 @@
 tail = %22
-c
+C
 an't cas
@@ -2359,17 +2359,17 @@
 return %22
-i
+I
 nvalid c
@@ -2388,16 +2388,17 @@
 unction 
+%5B
 %22 + udf.
@@ -2418,16 +2418,17 @@
 me() + %22
+%5D
 , %22 + po
@@ -2457,17 +2457,17 @@
 rgument 
-(
+%5B
 %22 + arg.
@@ -2479,17 +2479,17 @@
 me() + %22
-)
+%5D
  is of i
@@ -2777,8 +2777,9 @@
 h%22;%0A%09%7D%0A%7D
+%0A

improve UDF error messages