//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;

#if !WASM
namespace CommonHelpers {
#else
namespace CommonHelpers.WASM {
#endif

//**************************************************************************************************
/// <summary>
/// </summary>
public static partial class HArrayArgChecking {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static ArgumentException ArgumentException_EmptyArray =>
   new ArgumentException( "Array is empty." );

public static ArgumentOutOfRangeException ArgumentOutOfRangeException_IncorrectIndex =>
   HArgumentOutOfRangeExceptionCreator.Create( "Array index is incorrect." );

public static ArgumentException ArgumentException_IncorrectDimensionArgument =>
   HArgumentExceptionCreator.Create(
      "Array dimension argument is incorrect." );

//--------------------------------------------------------------------------------------------------

public static ArgumentException ArgumentException_NotOneDimensionalArray =>
   HArgumentExceptionCreator.Create(
      "Array type is not one dimensional array." );

//--------------------------------------------------------------------------------------------------

public static ArgumentException ArgumentException_ZeroBasedArrayExpected =>
   new ArgumentException( "Zero based array was expected." );

//--------------------------------------------------------------------------------------------------

public static ArgumentException ArgumentException_UniformLengthJuggedArrayExpected =>
   new ArgumentException( "Uniform length jugged array was expected." );

//==================================================================================================

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
public static void VerifyNotEmpty(Array array)
{
   HArgChecking.VerifyNotNull( array );
   if (array.Length==0)
      throw ArgumentException_EmptyArray;
}
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
public static T[] VerifyNotEmpty<T>(T[] array)
{
   VerifyNotEmpty( (Array)array ); return array;
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentOutOfRangeException" />
public static void VerifyIndex(Array array,int dimension,int index)
{
   HArgChecking.VerifyNotNull( array );
   if (!HArray.IsIndexInValidBounds(array,dimension,index))
      throw ArgumentOutOfRangeException_IncorrectIndex;
}
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentOutOfRangeException" />
public static T[] VerifyIndex<T>(T[] array,int dimension,int index)
{
   VerifyIndex( (Array)array, dimension, index ); return array;
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentOutOfRangeException" />
public static T[] VerifyIndex<T>(T[] array,int index)
{
   HArgChecking.VerifyNotNull( array );
   if (!HArray.IsIndexInValidBounds(array,index))
      throw ArgumentOutOfRangeException_IncorrectIndex;
   return array;
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentOutOfRangeException" />
public static T[,] VerifyIndex<T>(T[,] array,int dimension,int index)
{
   HArgChecking.VerifyNotNull( array );
   if (!HArray2D.IsIndexInValidBounds(array,dimension,index))
      throw ArgumentOutOfRangeException_IncorrectIndex;
   return array;
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
public static void VerifyDimension(Array array,int dimension)
{
   HArgChecking.VerifyNotNull( array );
   if (!HArray.IsValidDimension(array,dimension))
      throw ArgumentException_IncorrectDimensionArgument;
}
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
public static T[] VerifyDimension<T>(T[] array,int dimension)
{
   VerifyDimension( (Array)array, dimension ); return array;
}
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
public static T[,] VerifyDimension<T>(T[,] array,int dimension)
{
   HArgChecking.VerifyNotNull( array );
   if (!HArray2D.IsValidDimension(array,dimension))
      throw ArgumentException_IncorrectDimensionArgument;
   return array;
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
public static void VerifyOneDimensional(Array array)
{
   HArgChecking.VerifyNotNull( array );
   if ( array.Rank != 1 )
      throw ArgumentException_NotOneDimensionalArray;
}

//==================================================================================================

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
public static T[] VerifyZeroBasedIndexArray<T>(T[] array)
{
   HArgChecking.VerifyNotNull( array );
   if ( array.GetLowerBound(0) != 0 )
      throw ArgumentException_ZeroBasedArrayExpected;
   return array;
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
[CLSCompliant(false)]
public static T[][] VerifyZeroBasedIndexArray<T>(T[][] array)
{
   HArgChecking.VerifyNotNull( array );
   if ( array.GetLowerBound(0) != 0 )
      throw ArgumentException_ZeroBasedArrayExpected;
   foreach (T[] subArray in array)
      if ( subArray != null )
         VerifyZeroBasedIndexArray( subArray );
   return array;
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
[CLSCompliant(false)]
public static T[,] VerifyZeroBasedIndexArray<T>(T[,] array)
{
   HArgChecking.VerifyNotNull( array );
   if ( array.GetLowerBound(0)!=0 || array.GetLowerBound(1)!=0 )
      throw ArgumentException_ZeroBasedArrayExpected;
   return array;
}

//==================================================================================================

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
public static T[][] VerifyUniformLengthJuggedArray<T>(T[][] array)
{
   HArgChecking.VerifyNotNull( array );
   int len = -1;
   foreach (T[] subArray in array)
   {
      HArgChecking.VerifyNotNull( subArray );
      if ( len < 0 )
         len = subArray.Length;
      else
         if ( subArray.Length != len )      
            throw ArgumentException_UniformLengthJuggedArrayExpected;
   }
   return array;
}

//==================================================================================================

static HArrayArgChecking()
{
   CommonHelpers_Core.Access();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HArrayArgChecking
//**************************************************************************************************

} // CommonHelpers (.WASM)
