//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// UserRTX.NET satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define TRACE

using System;
using System.Reflection;
using System.Diagnostics;
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>
/// Automatic code-block trace (synchronous disposable)
/// </summary>
[u.sync_only_disposable]
public class TRACE_IF: u.DisposableSyncImpl<TRACE_IF> {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[MethodImpl(MethodImplOptions.NoInlining)]
public TRACE_IF( bool condition, string blockName )
{
   if ( condition && u.assembly.IsConfiguredForTrace( Assembly.GetCallingAssembly() ) )
      _blockTracer = new CodeBlockTracer( false, blockName );
   ValidateDisposable();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public TRACE_IF( bool condition, string blockNameFmt, params object?[] args )
{
   if ( condition && u.assembly.IsConfiguredForTrace( Assembly.GetCallingAssembly() ) )
      _blockTracer = new CodeBlockTracer( false, blockNameFmt, args );
   ValidateDisposable();
}

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

/// <exception cref="ArgumentNullException" />
[MethodImpl(MethodImplOptions.NoInlining)]
public TRACE_IF( bool condition, [u.req] MethodBase? method, bool expanded=true )
{
   if ( condition && u.assembly.IsConfiguredForTrace( Assembly.GetCallingAssembly() ) )
      _blockTracer = new CodeBlockTracer( false,
         u.arg_check.NN( method, nameof(method) ),
         expanded );
   ValidateDisposable();
}

/// <exception cref="ArgumentException" />
[MethodImpl(MethodImplOptions.NoInlining)]
public TRACE_IF( bool condition, Type objectType, [CallerMemberName] string memberName="" )
{
   if ( condition && u.assembly.IsConfiguredForTrace( Assembly.GetCallingAssembly() ) )
      _blockTracer = new CodeBlockTracer( false, objectType, memberName );
   ValidateDisposable();
}

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

protected override TRACE_IF DisposableSelf => this;

protected override void OnSyncDispose() =>
   _blockTracer?.DoDispose();

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

u.CodeBlockTracer? _blockTracer;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // TRACE_IF

} // user_rtx (.wasm)
