using System;

namespace Volpe.Cafe.Utils
{
    /// <summary>
    /// Provides extension methods for arrays, such as cloning, sorting, and searching.
    /// </summary>
    [Serializable]
    public static class ArrayExtension
    {
        /// <summary>
        /// Creates a shallow copy of a one-dimensional array of type T.
        /// </summary>
        /// <typeparam name="T">The type of the elements of the array.</typeparam>
        /// <param name="array">The array to clone.</param>
        /// <returns>A shallow copy of a one-dimensional array of type T.</returns>
        /// <remarks>
        /// For primitive types (e.g., int, double), immutable types (e.g., string), and value types (structs) where
        /// all members are also recursively primitive, immutable, or value types, cloning results in a deep copy.
        /// </remarks>
        public static T[] CloneArray<T>(this T[] array)
        {
            return (T[])array.Clone();
        }

        /// <summary>
        /// Creates a deep copy of a one-dimensional array of type T by executing the specified cloneT delegate on each
        /// member of the array.
        /// </summary>
        /// <typeparam name="T">The type of the elements of the array.</typeparam>
        /// <param name="array">The array to clone.</param>
        /// <param name="cloneT">Encapsulates a method that will handle cloning for each element of the array.</param>
        /// <returns>A deep copy of a one-dimensional array of type T.</returns>
        public static T[] CloneArray<T>(this T[] array, Func<T, T> cloneT)
        {
            T[] newArray = new T[array.Length];
            for (int i = 0; i < array.Length; i++) {
                newArray[i] = cloneT(array[i]);
            }
            return newArray;
        }

        /// <summary>
        /// Sorts the elements in an entire array using the <see cref="System.IComparable{T}"/> generic interface
        /// implementation of each element of the array.
        /// </summary>
        /// <typeparam name="T">The type of the elements of the array.</typeparam>
        /// <param name="array">The array to examine.</param>
        public static void Sort<T>(this T[] array) where T : IComparable<T>
        {
            Array.Sort(array);
        }
    }
}
