//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// UserRTX.NET satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
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>
/// Non-nullable property support (strict access to underlying value)
/// </summary>
public static class property_nn {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="ArgumentException" />
/// <exception cref="NullReferenceException" />
[u.strict_result]
public static T Get<T>( object obj, T? value,
                        [CallerMemberName] string getMethodName="" )
where T: class =>
   value ?? throw new NullReferenceException(string.Format(
      "Reference property is not initialized: “{0}.{1}”.",
      obj.GetType(), PropertyName( getMethodName ) ));

/// <exception cref="ArgumentException" />
/// <exception cref="u.ENullValue" />
[u.strict_result]
public static T Value<T>( object obj, T? nullableValue,
                          [CallerMemberName] string getMethodName="" )
where T: struct =>
   nullableValue.HasValue ? nullableValue.Value :
      throw e_null_value.New(
         "Value property is not initialized: “{0}.{1}”.",
         obj.GetType(), PropertyName( getMethodName ) );

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

/// <exception cref="ArgumentException" />
public static string NameAuto( [CallerMemberName] string propertyName="" ) =>
   u.arg_check.NN( propertyName, nameof(propertyName) ) != "" ? propertyName :
      throw new ArgumentException( "Property name is empty.", nameof(propertyName) );

/// <exception cref="ArgumentException" />
public static string NameAutoN( [CallerMemberName] string propertyName="" )
{
   if ( u.arg_check.NN( propertyName, nameof(propertyName) ) == "" )
      throw new ArgumentException( "Property name is empty.", nameof(propertyName) );
   if ( !propertyName.StartsWith( "N" ) )
      throw new ArgumentException(
         "Property name must start with “N” (case sensitive).",
         nameof(propertyName) );
   if ( propertyName == "N" )
      throw new ArgumentException( "Property name must not equal “N”.", nameof(propertyName) );
   return propertyName.Substring( 1 );
}

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

static string PropertyName( string? getMethodName ) =>
   getMethodName ?? "???";

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // property_nn

} // user_rtx (.wasm)
