//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;

namespace CommonHelpers {

//**************************************************************************************************
static partial class HDB {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidCastException" />
/// <exception cref="HDatabaseException" />
[HOptionalResult]
public static T GetFieldValue<T>( SqlDataReader dataReader, string fieldName,
                                  [HOptional] IDictionary<string,int>? fieldIndexer,
                                  bool treatNullAsDefaultValue = false ) =>
   GetFieldValue<T>( null, dataReader, fieldName, fieldIndexer, treatNullAsDefaultValue );

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidCastException" />
[HOptionalResult][HOptionalThroughMinusOne]
public static int GetFieldIndex( SqlDataReader dataReader, string fieldName,
                                 [HOptional] IDictionary<string,int>? fieldIndexer,
                                 bool throwIfNotFound = false ) =>
   GetFieldIndex( null, dataReader, fieldName, fieldIndexer, throwIfNotFound );

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidCastException" />
/// <exception cref="HDatabaseException" />
[HOptionalResult][HOptionalThroughMinusOne]
public static int GetFieldIndex( [HOptional] string? procedureName,
                                 SqlDataReader dataReader, string fieldName,
                                 [HOptional] IDictionary<string,int>? fieldIndexer,
                                 bool throwIfNotFound = false )
{
   HArgChecking.VerifyNotNulls( dataReader, fieldName );
   int fieldIdx = -1;
   if ( fieldIndexer != null )
      if ( !fieldIndexer.TryGetValue( fieldName, out fieldIdx ) )
         fieldIdx = -1;
      else
      {
         if ( !HOps.IsBetween( fieldIdx, 0, dataReader.FieldCount-1 ) )
            throw HDBExceptionCreator.Create(HLocal.TEXT(
               "Field \"{0}\" was incorrectly found in provided result-set field indexer.{1}",
               "Поле \"{0}\" было некорректно найдено в индексаторе полей резалт-сета.{1}" ),
               fieldName, LFnStoredProcOrEmpty( procedureName ) );
         if ( !HString.Equals( dataReader.GetName( fieldIdx ), fieldName, true ) )
            fieldIdx = -1;
      }
   if ( fieldIdx < 0 )
   {
      try { fieldIdx = dataReader.GetOrdinal( fieldName ); }
      catch (IndexOutOfRangeException) {
         if ( throwIfNotFound )
            throw HDBExceptionCreator.Create(HLocal.TEXT(
               "Field is not found in result-set: \"{0}\".{1}",
               "Поле в резалт-сете не найдено: \"{0}\".{1}"),
               fieldName, LFnStoredProcOrEmpty( procedureName ) ); }
      if ( fieldIdx >= 0 && fieldIndexer != null )
         fieldIndexer[ fieldName ] = fieldIdx;
   }
   return fieldIdx;
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidCastException" />
[HOptionalResult]
public static int GetSPReturnValue( string procedureName, SqlParameter returnValueParam ) =>
   GetSPReturnValue<int>( procedureName, returnValueParam );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HDB
//**************************************************************************************************

} // CommonHelpers
