//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// UserRTX.NET satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Reflection;
using System.Runtime.CompilerServices;

#if !WASM
namespace user_rtx { using u = user_rtx;
#else
namespace user_rtx.wasm { using u = user_rtx.wasm;
#endif

/// <summary>
/// Property checking (for value extractors)
/// </summary>
public static class prop_check {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static T Initialized<T>( T? value, string propertyFullName )
where T: class =>
   value ?? throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
      u.str_argcheck.NE( propertyFullName, nameof(propertyFullName) ));

/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static T Initialized<T>( T? value, Type objectType,
                                [CallerMemberName] string propertyName="" )
where T: class =>
   value ?? throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
      objectType, u.str_argcheck.NE( propertyName, nameof(propertyName) ));

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static T Initialized<T>( T? value, MethodBase? propertyMethod )
where T: class =>
   value ?? throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
      u.arg_check.NN( propertyMethod, nameof(propertyMethod) ));

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

/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static T InitializedNV<T>( T? value, string propertyFullName )
where T: struct =>
   value.HasValue ? value.Value :
      throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
         u.str_argcheck.NE( propertyFullName, nameof(propertyFullName) ));

/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static T InitializedNV<T>( T? value, Type objectType,
                                  [CallerMemberName] string propertyName="" )
where T: struct =>
   value.HasValue ? value.Value :
      throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
         objectType, u.str_argcheck.NE( propertyName, nameof(propertyName) ));

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static T InitializedNV<T>( T? value, [u.req] MethodBase? propertyMethod )
where T: struct =>
   value.HasValue ? value.Value :
      throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
         u.arg_check.NN( propertyMethod, nameof(propertyMethod) ));

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

/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static bool InitializedIntBool( int value, string propertyFullName ) =>
   value == -1 ?
      throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
         u.str_argcheck.NE( propertyFullName, nameof(propertyFullName) ))
      : u.boolean.FromInt( value );

/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static bool InitializedIntBool( int value, Type objectType,
                                       [CallerMemberName] string propertyName="" ) =>
   value == -1 ?
      throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
         objectType, u.str_argcheck.NE( propertyName, nameof(propertyName) ))
      : u.boolean.FromInt( value );

/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[u.returns_source]
public static bool InitializedIntBool( int value, [u.req] MethodBase? propertyMethod ) =>
   value == -1 ?
      throw propcheck_errors.PROPERTY_NOT_INITIALIZED(
         u.arg_check.NN( propertyMethod, nameof(propertyMethod) ))
      : u.boolean.FromInt( value );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // prop_check

} // user_rtx (.wasm)
