#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().ToUpper(CultureInfo.InvariantCulture);
			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
	}
}
