//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.IO;
using System.Reflection;

#if !WASM
namespace CommonHelpers {
#else
namespace CommonHelpers.WASM {
#endif

//**************************************************************************************************
partial class HAssembly {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static AssemblyName GetCallingAssemblyName()
{
   return Assembly.GetCallingAssembly().GetName();
}

public static string GetCallingAssemblySimpleName()
{
   return Assembly.GetCallingAssembly().GetName().Name;
}

public static string GetCallingAssemblyCodeBase()
{
   return Assembly.GetCallingAssembly().GetName().CodeBase;
}

/// <exception cref="HOperationFailedException" />
public static string GetCallingAssemblyModuleName()
{
   string codeBase = Assembly.GetCallingAssembly().GetName().CodeBase;
   if (HString.IsBlank(codeBase))
      throw new HOperationFailedException();
   return Path.GetFileName( codeBase );
}

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

public static bool IsEntryAssembly()
{
   return IsEntryAssembly( Assembly.GetCallingAssembly() );
}

public static bool IsEntryAssembly(Assembly assembly)
{
   HArgChecking.VerifyNotNull( assembly );
   var entryAssembly =
      Assembly.GetEntryAssembly();
   return
      entryAssembly!=null &&
      assembly.FullName==entryAssembly.FullName;
}

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

/// <exception cref="HElementNotFoundException" />
public static Assembly AssemblyByName(string fullOrPartialName)
{
   return GetByName(fullOrPartialName,true);
}

/// <exception cref="HElementNotFoundException" />
public static Assembly GetByName(string fullOrPartialName)
{
   return GetByName(fullOrPartialName,false);
}

/// <exception cref="HElementNotFoundException" />
public static Assembly GetByName(string fullOrPartialName,bool throwOnFailure)
{
   HStringArgChecking.VerifyNotNullOrEmpty(fullOrPartialName);

   foreach ( var assembly in AppDomain.CurrentDomain.GetAssemblies() )
   {
      var assemblyName = assembly.GetName();
      if ( HString.Equals(assemblyName.FullName,fullOrPartialName,true) ||
           HString.Equals(assemblyName.Name,fullOrPartialName,true) ) 
         return assembly;
   }

   if (throwOnFailure)
      throw HElementNotFoundExceptionCreator.Create(
         "Assembly \"{0}\" has not been loaded into domain.",
         fullOrPartialName );

   return null;
}

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

public static Assembly GetOrLoadAssemblyWithArchitecture(string simpleName,string loadName)
{
   return GetOrLoadAssemblyWithArchitecture( simpleName, loadName, null );
}

public static Assembly GetOrLoadAssemblyWithArchitecture( string simpleName,
                                                          string loadNameFmt,
                                                          params object[] parameters )
{
   HArgChecking.VerifyNotNulls( simpleName, loadNameFmt, parameters );
   return GetOrLoadAssemblyWithArchitecture( null, simpleName, loadNameFmt, parameters );
}

//--------------------------------------------------------------------------------------------------
#if WIN32

public static Assembly GetOrLoadAssemblyWithArchitecture
(
   ProcessorArchitecture? processorArchitecture, string simpleName, string loadName
)
{
   HArgChecking.VerifyNotNulls( simpleName, loadName );

   var assembly = GetLoadedAssembly( simpleName );
   if ( assembly != null ) return assembly;

   var assemblyName = new AssemblyName( loadName );
   assemblyName.ProcessorArchitecture = processorArchitecture ?? HPlatform.ProcessorArchitecture;

   return Assembly.Load( assemblyName );
}

public static Assembly GetOrLoadAssemblyWithArchitecture
(
   ProcessorArchitecture? processorArchitecture,
   string simpleName, string loadNameFmt, params object[] parameters
)
{
   HArgChecking.VerifyNotNulls( simpleName, loadNameFmt, parameters );
   return GetOrLoadAssemblyWithArchitecture( processorArchitecture,
      simpleName, string.Format( loadNameFmt, parameters ) );
}

#endif // WIN32
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HAssembly
//**************************************************************************************************

} // CommonHelpers (.WASM)
