using System;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;

using CommonHelpers;

namespace MyFlat {

//**************************************************************************************************
partial class XControllerBase {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="InvalidOperationException" />
[HAsyncStatic]
protected dynamic DoDynamic( string methodNameOrSignature, Func<dynamic> body ) =>
   DoDynamic( body, methodNameOrSignature );

/// <exception cref="InvalidOperationException" />
[HAsyncStatic]
protected dynamic DoDynamic( Func<dynamic> body,
                             [CallerMemberName][HRequired] string? methodNameOrSignature=null )
{
   BeginDo( HArgChecking.NN( methodNameOrSignature ) );
   try {
      return body();
   }
   catch (Exception e) {
      ReportException( e );
      return new StatusCodeResult( StatusCodes.Status500InternalServerError );
   }
   finally {
      EndDo();
   }
}

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

/// <exception cref="InvalidOperationException" />
/// <exception cref="HUnsuccessException" />
[HAsyncStatic]
protected dynamic DoDynamic<T>( string methodNameOrSignature,
                                Func<string,T> errorResponseCreator, Func<dynamic> body )
where T: class =>
   DoDynamic<T>( errorResponseCreator, body, methodNameOrSignature );

/// <exception cref="InvalidOperationException" />
/// <exception cref="HUnsuccessException" />
[HAsyncStatic]
protected dynamic DoDynamic<T>( Func<string,T> errorResponseCreator, Func<dynamic> body,
                                [CallerMemberName][HRequired] string? methodNameOrSignature=null )
where T: class
{
   VerifyNotActive();
   OnPrepareContext();
   _AsyncLocalInfo_.Value = new CurrentInfo( GetType(),
      HArgChecking.NN( methodNameOrSignature ) );
   PrintInMethod();
   try {
      return body();
   }
   catch (Exception e) {
      ReportException( e );
      return errorResponseCreator( MSG.ServerError( e ) ) ??
         throw ErrorResponseCreatorReturnedNull_Error;
   }
   finally {
      _AsyncLocalInfo_.Value = null;
      CON.FlushPendingNewLine();
   }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // XControllerBase
//**************************************************************************************************

} // MyFlat
