using System;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;

using CommonHelpers.WASM;

namespace BookRegistry.Client {

//**************************************************************************************************
/// <summary>
/// Non-nullable property support for inheritance (strict access to underlying value)
/// </summary>
public class PropertyNNBase {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="ArgumentNullException" />
/// <exception cref="NullReferenceException" />
[HStrictResult][HOptionalResult]
protected T Get<T>( T? value,
                    [CallerMemberName] string? propertyName=null )
where T: class =>
   IgnoreRefChecking ? value! : HPropertyNN.Get<T>( this, value, propertyName );

/// <exception cref="ArgumentNullException" />
/// <exception cref="HNullValueException" />
[HStrictResult]
protected T Value<T>( T? nullableValue,
                      [CallerMemberName] string? propertyName=null )
where T: struct =>
   HPropertyNN.Value<T>( this, nullableValue, propertyName );

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

[HStrictResult]
public static R ReturnIgnoreRefChecking<R>(Func<R> body)
{
   IgnoreRefChecking = true;
   try { return body(); }
   finally { IgnoreRefChecking = false; }
}

[HStrictResult]
public static async Task<R> ReturnIgnoreRefChecking_A<R>(Func<Task<R>> bodyA)
{
   IgnoreRefChecking = true;
   try { return await bodyA(); }
   finally { IgnoreRefChecking = false; }
}

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

[HAsyncStatic]
static bool IgnoreRefChecking {
   get => _AsyncStatic_IgnoreRefChecking_.Value;
   set => _AsyncStatic_IgnoreRefChecking_.Value = value;
}

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

static readonly AsyncLocal<bool>
   _AsyncStatic_IgnoreRefChecking_ = new AsyncLocal<bool>();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // PropertyNNBase
//**************************************************************************************************

} // BookRegistry.Client
