//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// AFXUI auxiliary module for Blazor-application (WASM) | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Collections.Generic;

using CommonHelpers.WASM;
using AFXUI;

namespace BookRegistry.Client {

//**************************************************************************************************
public class ServiceInvocationResult<TResponse>
where TResponse: GeneralApiResponse {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public TResponse? Response { get; }
public Exception? Exception { get; }
public string? ErrorMessage { get; }

public bool HasResponse => Response != null;
public bool HasError => ErrorMessage != null;
public bool Success => !HasError;
public Guid? Status => Response?.Status;
public string? SpecialCategory => Response?.SpecialCategory;

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

/// <exception cref="InvalidOperationException" />
public TResponse ResponseNN => DoVerifyHasResponse();
/// <exception cref="InvalidOperationException" />
public Exception ExceptionNN => DoVerifyHasException();

/// <exception cref="InvalidOperationException" />
public string ErrorMessageNN =>
   ErrorMessage ?? throw new InvalidOperationException(
      "\"ErrorMessage\"-property is null (\"ServiceInvocationResult\")." );

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

public ServiceInvocationResult(TResponse response)
: this( response, null )
{}
public ServiceInvocationResult(Exception exception)
: this( null, exception )
{}

/// <exception cref="ArgumentException" />
public ServiceInvocationResult( TResponse? response, Exception? exception )
{
   HasRequestError( response, exception );
   Response = response;
   Exception = exception;
   if ( exception != null )
      ErrorMessage = HException.GetErrorMessage( exception );
   else
   {
      response = response.NN();
      if ( response.HasError )
         ErrorMessage = response.Message;
   }
}

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

/// <exception cref="InvalidOperationException" />
public void VerifyHasResponse() => DoVerifyHasResponse();
/// <exception cref="InvalidOperationException" />
public void VerifyHasException() => DoVerifyHasException();

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

public static implicit operator ServiceInvocationResult<GeneralApiResponse>
   ( ServiceInvocationResult<TResponse> invocationResult ) =>
      new ServiceInvocationResult<GeneralApiResponse>(
         invocationResult.Response, invocationResult.Exception );

public static implicit operator SimpleSIR
   ( ServiceInvocationResult<TResponse> invocationResult ) =>
      new SimpleSIR( invocationResult.Response, invocationResult.Exception );

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

/// <exception cref="ArgumentException" />
public static bool HasRequestError( [HRelOpt] GeneralApiResponse? response,
                                    [HRelOpt] Exception? error )
{
   if ( response==null && error==null )
      throw new ArgumentException(
         "Both arguments for \"ServiceInvocationResult.HasRequestError\" are null." );
   if ( response!=null && error!=null )
      throw new ArgumentException(
         "Both arguments for \"ServiceInvocationResult.HasRequestError\" are not null." );
   return error!=null || response==null || response.HasError;
}

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

/// <exception cref="InvalidOperationException" />
TResponse DoVerifyHasResponse() =>
   Response ?? throw new InvalidOperationException(
      "\"Response\"-property is null (\"ServiceInvocationResult\")." );
/// <exception cref="InvalidOperationException" />
Exception DoVerifyHasException() =>
   Exception ?? throw new InvalidOperationException(
      "\"Exception\"-property is null (\"ServiceInvocationResult\")." );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // ServiceInvocationResult
//**************************************************************************************************

} // BookRegistry.Client
