#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more 
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership. 
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with 
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
using System.Text;

using log4net.Core;
using log4net.Util.TypeConverters;

namespace log4net.Util
{
	/// <summary>
	/// A convenience class to convert property values to specific types.
	/// </summary>
	/// <remarks>
	/// <para>
	/// Utility functions for converting types and parsing values.
	/// </para>
	/// </remarks>
	/// <author>Nicko Cadell</author>
	/// <author>Gert Driesen</author>
	public sealed class OptionConverter
	{
		#region Private Instance Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="OptionConverter" /> class. 
		/// </summary>
		/// <remarks>
		/// <para>
		/// Uses a private access modifier to prevent instantiation of this class.
		/// </para>
		/// </remarks>
		private OptionConverter()
		{
		}

		#endregion Private Instance Constructors

		#region Public Static Methods

//		/// <summary>
//		/// Concatenates two string arrays.
//		/// </summary>
//		/// <param name="l">Left array.</param>
//		/// <param name="r">Right array.</param>
//		/// <returns>Array containing both left and right arrays.</returns>
//		public static string[] ConcatenateArrays(string[] l, string[] r) 
//		{
//			return (string[])ConcatenateArrays(l, r);
//		}

//		/// <summary>
//		/// Concatenates two arrays.
//		/// </summary>
//		/// <param name="l">Left array</param>
//		/// <param name="r">Right array</param>
//		/// <returns>Array containing both left and right arrays.</returns>
//		public static Array ConcatenateArrays(Array l, Array r) 
//		{
//			if (l == null)
//			{
//				throw new ArgumentNullException("l");
//			}
//			if (r == null)
//			{
//				throw new ArgumentNullException("r");
//			}
//
//			int len = l.Length + r.Length;
//			Array a = Array.CreateInstance(l.GetType(), len);
//
//			Array.Copy(l, 0, a, 0, l.Length);
//			Array.Copy(r, 0, a, l.Length, r.Length);
//
//			return a;
//		}
  
//		/// <summary>
//		/// Converts string escape characters back to their correct values.
//		/// </summary>
//		/// <param name="s">String to convert.</param>
//		/// <returns>Converted result.</returns>
//		public static string ConvertSpecialChars(string s) 
//		{
//			if (s == null)
//			{
//				throw new ArgumentNullException("s");
//			}
//			char c;
//			int len = s.Length;
//			StringBuilder buf = new StringBuilder(len);
//	
//			int i = 0;
//			while(i < len) 
//			{
//				c = s[i++];
//				if (c == '\\') 
//				{
//					c =  s[i++];
//					if (c == 'n')	  c = '\n';
//					else if (c == 'r') c = '\r';
//					else if (c == 't') c = '\t';
//					else if (c == 'f') c = '\f';
//					else if (c == '\b') c = '\b';					
//					else if (c == '\"') c = '\"';				
//					else if (c == '\'') c = '\'';			
//					else if (c == '\\') c = '\\';			
//				}
//				buf.Append(c);	  
//			}
//			return buf.ToString();
//		}

		/// <summary>
		/// Converts a string to a <see cref="bool" /> value.
		/// </summary>
		/// <param name="argValue">String to convert.</param>
		/// <param name="defaultValue">The default value.</param>
		/// <returns>The <see cref="bool" /> value of <paramref name="argValue" />.</returns>
		/// <remarks>
		/// <para>
		/// If <paramref name="argValue"/> is "true", then <c>true</c> is returned. 
		/// If <paramref name="argValue"/> is "false", then <c>false</c> is returned. 
		/// Otherwise, <paramref name="defaultValue"/> is returned.
		/// </para>
		/// </remarks>
		public static bool ToBoolean(string argValue, bool defaultValue) 
		{
			if (argValue != null && argValue.Length > 0)
			{
				try
				{
					return bool.Parse(argValue);
				}
				catch(Exception e)
				{
					LogLog.Error(declaringType, "[" + argValue + "] is not in proper bool form.", e);
				}
			}
			return defaultValue;
		}

//		/// <summary>
//		/// Converts a string to an integer.
//		/// </summary>
//		/// <param name="argValue">String to convert.</param>
//		/// <param name="defaultValue">The default value.</param>
//		/// <returns>The <see cref="int" /> value of <paramref name="argValue" />.</returns>
//		/// <remarks>
//		/// <para>
//		/// <paramref name="defaultValue"/> is returned when <paramref name="argValue"/>
//		/// cannot be converted to a <see cref="int" /> value.
//		/// </para>
//		/// </remarks>
//		public static int ToInt(string argValue, int defaultValue) 
//		{
//			if (argValue != null) 
//			{
//				string s = argValue.Trim();
//				try 
//				{
//					return int.Parse(s, NumberFormatInfo.InvariantInfo);
//				}
//				catch (Exception e) 
//				{
//					LogLog.Error(declaringType, "OptionConverter: [" + s + "] is not in proper int form.", e);
//				}
//			}
//			return defaultValue;
//		}

		/// <summary>
		/// Parses a file size into a number.
		/// </summary>
		/// <param name="argValue">String to parse.</param>
		/// <param name="defaultValue">The default value.</param>
		/// <returns>The <see cref="long" /> value of <paramref name="argValue" />.</returns>
		/// <remarks>
		/// <para>
		/// Parses a file size of the form: number[KB|MB|GB] into a
		/// long value. It is scaled with the appropriate multiplier.
		/// </para>
		/// <para>
		/// <paramref name="defaultValue"/> is returned when <paramref name="argValue"/>
		/// cannot be converted to a <see cref="long" /> value.
		/// </para>
		/// </remarks>
		public static long ToFileSize(string argValue, long defaultValue) 
		{
			if (argValue == null)
			{
				return defaultValue;
			}
	
			string s = argValue.Trim().ToUpperInvariant();
			long multiplier = 1;
			int index;
	
			if ((index = s.IndexOf("KB")) != -1) 
			{	  
				multiplier = 1024;
				s = s.Substring(0, index);
			}
			else if ((index = s.IndexOf("MB")) != -1) 
			{
				multiplier = 1024 * 1024;
				s = s.Substring(0, index);
			}
			else if ((index = s.IndexOf("GB")) != -1) 
			{
				multiplier = 1024 * 1024 * 1024;
				s = s.Substring(0, index);
			}	
			if (s != null) 
			{
				// Try again to remove whitespace between the number and the size specifier
				s = s.Trim();
				
				long longVal;
				if (SystemInfo.TryParse(s, out longVal))
				{
					return longVal * multiplier;
				}
				else
				{
					LogLog.Error(declaringType, "OptionConverter: ["+ s +"] is not in the correct file size syntax.");
				}
			}
			return defaultValue;
		}

		/// <summary>
		/// Converts a string to an object.
		/// </summary>
		/// <param name="target">The target type to convert to.</param>
		/// <param name="txt">The string to convert to an object.</param>
		/// <returns>
		/// The object converted from a string or <c>null</c> when the 
		/// conversion failed.
		/// </returns>
		/// <remarks>
		/// <para>
		/// Converts a string to an object. Uses the converter registry to try
		/// to convert the string value into the specified target type.
		/// </para>
		/// </remarks>
		public static object ConvertStringTo(Type target, string txt)
		{
			if (target == null)
			{
				throw new ArgumentNullException("target");
			}

			// If we want a string we already have the correct type
			if (typeof(string) == target || typeof(object) == target)
			{
				return txt;
			}

			// First lets try to find a type converter
			IConvertFrom typeConverter = ConverterRegistry.GetConvertFrom(target);
			if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
			{
				// Found appropriate converter
				return typeConverter.ConvertFrom(txt);
			}
			else
			{
#if NETSTANDARD1_3
				if (target.GetTypeInfo().IsEnum)
#else
				if (target.IsEnum)
#endif
				{
					// Target type is an enum.

					// Use the Enum.Parse(EnumType, string) method to get the enum value
					return ParseEnum(target, txt, true);
				}
				else
				{
					// We essentially make a guess that to convert from a string
					// to an arbitrary type T there will be a static method defined on type T called Parse
					// that will take an argument of type string. i.e. T.Parse(string)->T we call this
					// method to convert the string to the type required by the property.
					System.Reflection.MethodInfo meth = target.GetMethod("Parse", new Type[] {typeof(string)});
					if (meth != null)
					{
						// Call the Parse method
#if NETSTANDARD1_3
						return meth.Invoke(target, new[] { txt });
#else
						return meth.Invoke(null, BindingFlags.InvokeMethod, null, new object[] {txt}, CultureInfo.InvariantCulture);
#endif
					}
					else
					{
						// No Parse() method found.
					}
				}
			}
			return null;
		}

//		/// <summary>
//		/// Looks up the <see cref="IConvertFrom"/> for the target type.
//		/// </summary>
//		/// <param name="target">The type to lookup the converter for.</param>
//		/// <returns>The converter for the specified type.</returns>
//		public static IConvertFrom GetTypeConverter(Type target)
//		{
//			IConvertFrom converter = ConverterRegistry.GetConverter(target);
//			if (converter == null)
//			{
//				throw new InvalidOperationException("No type converter defined for [" + target + "]");
//			}
//			return converter;
//		}

		/// <summary>
		/// Checks if there is an appropriate type conversion from the source type to the target type.
		/// </summary>
		/// <param name="sourceType">The type to convert from.</param>
		/// <param name="targetType">The type to convert to.</param>
		/// <returns><c>true</c> if there is a conversion from the source type to the target type.</returns>
		/// <remarks>
		/// Checks if there is an appropriate type conversion from the source type to the target type.
		/// <para>
		/// </para>
		/// </remarks>
		public static bool CanConvertTypeTo(Type sourceType, Type targetType)
		{
			if (sourceType == null || targetType == null)
			{
				return false;
			}

			// Check if we can assign directly from the source type to the target type
			if (targetType.IsAssignableFrom(sourceType))
			{
				return true;
			}

			// Look for a To converter
			IConvertTo tcSource = ConverterRegistry.GetConvertTo(sourceType, targetType);
			if (tcSource != null)
			{
				if (tcSource.CanConvertTo(targetType))
				{
					return true;
				}
			}

			// Look for a From converter
			IConvertFrom tcTarget = ConverterRegistry.GetConvertFrom(targetType);
			if (tcTarget != null)
			{
				if (tcTarget.CanConvertFrom(sourceType))
				{
					return true;
				}
			}

			return false;
		}

		/// <summary>
		/// Converts an object to the target type.
		/// </summary>
		/// <param name="sourceInstance">The object to convert to the target type.</param>
		/// <param name="targetType">The type to convert to.</param>
		/// <returns>The converted object.</returns>
		/// <remarks>
		/// <para>
		/// Converts an object to the target type.
		/// </para>
		/// </remarks>
		public static object ConvertTypeTo(object sourceInstance, Type targetType)
		{
			Type sourceType = sourceInstance.GetType();

			// Check if we can assign directly from the source type to the target type
			if (targetType.IsAssignableFrom(sourceType))
			{
				return sourceInstance;
			}

			// Look for a TO converter
			IConvertTo tcSource = ConverterRegistry.GetConvertTo(sourceType, targetType);
			if (tcSource != null)
			{
				if (tcSource.CanConvertTo(targetType))
				{
					return tcSource.ConvertTo(sourceInstance, targetType);
				}
			}

			// Look for a FROM converter
			IConvertFrom tcTarget = ConverterRegistry.GetConvertFrom(targetType);
			if (tcTarget != null)
			{
				if (tcTarget.CanConvertFrom(sourceType))
				{
					return tcTarget.ConvertFrom(sourceInstance);
				}
			}

			throw new ArgumentException("Cannot convert source object [" + sourceInstance.ToString() + "] to target type [" + targetType.Name + "]", "sourceInstance");
		}

//		/// <summary>
//		/// Finds the value corresponding to <paramref name="key"/> in 
//		/// <paramref name="props"/> and then perform variable substitution 
//		/// on the found value.
//		/// </summary>
//		/// <param name="key">The key to lookup.</param>
//		/// <param name="props">The association to use for lookups.</param>
//		/// <returns>The substituted result.</returns>
//		public static string FindAndSubst(string key, System.Collections.IDictionary props) 
//		{
//			if (props == null)
//			{
//				throw new ArgumentNullException("props");
//			}
//
//			string v = props[key] as string;
//			if (v == null) 
//			{
//				return null;	  
//			}
//	
//			try 
//			{
//				return SubstituteVariables(v, props);
//			} 
//			catch(Exception e) 
//			{
//				LogLog.Error(declaringType, "OptionConverter: Bad option value [" + v + "].", e);
//				return v;
//			}	
//		}

		/// <summary>
		/// Instantiates an object given a class name.
		/// </summary>
		/// <param name="className">The fully qualified class name of the object to instantiate.</param>
		/// <param name="superClass">The class to which the new object should belong.</param>
		/// <param name="defaultValue">The object to return in case of non-fulfillment.</param>
		/// <returns>
		/// An instance of the <paramref name="className"/> or <paramref name="defaultValue"/>
		/// if the object could not be instantiated.
		/// </returns>
		/// <remarks>
		/// <para>
		/// Checks that the <paramref name="className"/> is a subclass of
		/// <paramref name="superClass"/>. If that test fails or the object could
		/// not be instantiated, then <paramref name="defaultValue"/> is returned.
		/// </para>
		/// </remarks>
		public static object InstantiateByClassName(string className, Type superClass, object defaultValue) 
		{
			if (className != null) 
			{
				try 
				{
#if NETSTANDARD1_3
					Type classObj = SystemInfo.GetTypeFromString(superClass.GetTypeInfo().Assembly, className, true, true);
#else
					Type classObj = SystemInfo.GetTypeFromString(className, true, true);
#endif
					if (!superClass.IsAssignableFrom(classObj)) 
					{
						LogLog.Error(declaringType, "OptionConverter: A [" + className + "] object is not assignable to a [" + superClass.FullName + "] variable.");
						return defaultValue;	  
					}
					return Activator.CreateInstance(classObj);
				}
				catch (Exception e) 
				{
					LogLog.Error(declaringType, "Could not instantiate class [" + className + "].", e);
				}
			}
			return defaultValue;	
		}

		/// <summary>
		/// Performs variable substitution in string <paramref name="value"/> from the 
		/// values of keys found in <paramref name="props"/>.
		/// </summary>
		/// <param name="value">The string on which variable substitution is performed.</param>
		/// <param name="props">The dictionary to use to lookup variables.</param>
		/// <returns>The result of the substitutions.</returns>
		/// <remarks>
		/// <para>
		/// The variable substitution delimiters are <b>${</b> and <b>}</b>.
		/// </para>
		/// <para>
		/// For example, if props contains <c>key=value</c>, then the call
		/// </para>
		/// <para>
		/// <code lang="C#">
		/// string s = OptionConverter.SubstituteVariables("Value of key is ${key}.");
		/// </code>
		/// </para>
		/// <para>
		/// will set the variable <c>s</c> to "Value of key is value.".
		/// </para>
		/// <para>
		/// If no value could be found for the specified key, then substitution 
		/// defaults to an empty string.
		/// </para>
		/// <para>
		/// For example, if system properties contains no value for the key
		/// "nonExistentKey", then the call
		/// </para>
		/// <para>
		/// <code lang="C#">
		/// string s = OptionConverter.SubstituteVariables("Value of nonExistentKey is [${nonExistentKey}]");
		/// </code>
		/// </para>
		/// <para>
		/// will set <s>s</s> to "Value of nonExistentKey is []".	 
		/// </para>
		/// <para>
		/// An Exception is thrown if <paramref name="value"/> contains a start 
		/// delimiter "${" which is not balanced by a stop delimiter "}". 
		/// </para>
		/// </remarks>
		public static string SubstituteVariables(string value, System.Collections.IDictionary props) 
		{
			StringBuilder buf = new StringBuilder();

			int i = 0;
			int j, k;
	
			while(true) 
			{
				j = value.IndexOf(DELIM_START, i);
				if (j == -1) 
				{
					if (i == 0)
					{
						return value;
					}
					else 
					{
						buf.Append(value.Substring(i, value.Length - i));
						return buf.ToString();
					}
				}
				else 
				{
					buf.Append(value.Substring(i, j - i));
					k = value.IndexOf(DELIM_STOP, j);
					if (k == -1) 
					{
						throw new LogException("[" + value + "] has no closing brace. Opening brace at position [" + j + "]");
					}
					else 
					{
						j += DELIM_START_LEN;
						string key = value.Substring(j, k - j);

						string replacement = props[key] as string;

						if (replacement != null) 
						{
							buf.Append(replacement);
						}
						i = k + DELIM_STOP_LEN;		
					}
				}
			}
		}

		#endregion Public Static Methods

		#region Private Static Methods

		/// <summary>
		/// Converts the string representation of the name or numeric value of one or 
		/// more enumerated constants to an equivalent enumerated object.
		/// </summary>
		/// <param name="enumType">The type to convert to.</param>
		/// <param name="value">The enum string value.</param>
		/// <param name="ignoreCase">If <c>true</c>, ignore case; otherwise, regard case.</param>
		/// <returns>An object of type <paramref name="enumType" /> whose value is represented by <paramref name="value" />.</returns>
		private static object ParseEnum(System.Type enumType, string value, bool ignoreCase) 
		{
#if !NETCF
			return Enum.Parse(enumType, value, ignoreCase);
#else
			FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);

			string[] names = value.Split(new char[] {','});
			for (int i = 0; i < names.Length; ++i) 
			{
				names[i] = names [i].Trim();
			}

			long retVal = 0;

			try 
			{
				// Attempt to convert to numeric type
				return Enum.ToObject(enumType, Convert.ChangeType(value, typeof(long), CultureInfo.InvariantCulture));
			} 
			catch {}

			foreach (string name in names) 
			{
				bool found = false;
				foreach(FieldInfo field in fields) 
				{
					if (String.Compare(name, field.Name, ignoreCase) == 0) 
					{
						retVal |= ((IConvertible) field.GetValue(null)).ToInt64(CultureInfo.InvariantCulture);
						found = true;
						break;
					}
				}
				if (!found) 
				{
					throw new ArgumentException("Failed to lookup member [" + name + "] from Enum type [" + enumType.Name + "]");
				}
			}
			return Enum.ToObject(enumType, retVal);
#endif
		}		

		#endregion Private Static Methods

		#region Private Static Fields

        /// <summary>
        /// The fully qualified type of the OptionConverter class.
        /// </summary>
        /// <remarks>
        /// Used by the internal logger to record the Type of the
        /// log message.
        /// </remarks>
        private readonly static Type declaringType = typeof(OptionConverter);

		private const string DELIM_START = "${";
		private const char   DELIM_STOP  = '}';
		private const int DELIM_START_LEN = 2;
		private const int DELIM_STOP_LEN  = 1;

		#endregion Private Static Fields
	}
}
