//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// UserRTX.NET satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Threading;
using System.Diagnostics;

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

/// <summary>
/// Fatal termination
/// </summary>
public static partial class fatal {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class DataAL {
   public bool IsInRaiseErrorThread { get; set; }
   public StackTrace? DispatcherCallerCurrentStack { get; set; }
} // DataAL
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static object SyncRoot => _syncRoot;
public static bool IsInRaiseError => _isInRaiseError;
[u.async_local]
public static bool IsInRaiseErrorThread {
   get {
      var data = DataAL_N;
      return data != null ? data.IsInRaiseErrorThread : false; }
   private set =>
      GetDataAL().IsInRaiseErrorThread = value; }

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

public static u.FatalCfg Settings {
   get { lock (SyncRoot) return _settings; }
   set { lock (SyncRoot) _settings = value; }}

public static bool RaiseOnUnhandledException
{
   get {
      lock ( SyncRoot )
         return _raiseOnUnhandledException;
   }
   set {
      lock ( SyncRoot )
         if ( value != _raiseOnUnhandledException ) {
            if ( value )
               AppDomain.CurrentDomain.UnhandledException +=
                  u.fatal_impl.AppDomainUnhandledException_Handler;
            else
               AppDomain.CurrentDomain.UnhandledException -=
                  u.fatal_impl.AppDomainUnhandledException_Handler;
            _raiseOnUnhandledException = value;
         }
   }
}

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

[u.async_local]
public static StackTrace? DispatcherCallerCurrentStack {
   get => DataAL_N?.DispatcherCallerCurrentStack;
   internal set => GetDataAL().DispatcherCallerCurrentStack = value; }

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

[u.async_local]
static DataAL? DataAL_N => _dataAL.Value;

[u.async_local]
static DataAL GetDataAL() =>
   _dataAL.Value ?? (_dataAL.Value = new DataAL());

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

static readonly object _syncRoot = new ();
static u.FatalCfg _settings = new FatalCfg();
static volatile bool _isInRaiseError;
static bool _raiseOnUnhandledException;
static readonly AsyncLocal<DataAL?> _dataAL = new();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // fatal

} // user_rtx (.wasm)
