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

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

//**************************************************************************************************
partial class HProgram {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="InvalidOperationException" />
public static bool IsProcessOwner
{
   get
   {
      int isProcessOwner = _IsProcessOwner_;
      if ( isProcessOwner == -1 )
         throw new InvalidOperationException(
            "Process owner flag has not been specified." );
      return isProcessOwner == 1;
   }
}
public static bool? IsProcessOwnerSpecification
{
   get { return HOps.IntToNullableBool( _IsProcessOwner_ ); }
}

public static void SpecifyIsProcessOwner()
{
   SpecifyIsProcessOwner( true );
}
public static void SpecifyIsProcessOwner(bool? value)
{
   _IsProcessOwner_ = HOps.NullableBoolToInt( value );
}

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

/// <exception cref="InvalidOperationException" />
public static bool InteractsWithDesktop
{
   get
   {
      int interactsWithDesktop = _InteractsWithDesktop_;
      if ( interactsWithDesktop == -1 )
         throw new InvalidOperationException(
            "Desktop interaction flag has not been specified." );
      return interactsWithDesktop == 1;
   }
}
public static bool? InteractsWithDesktopSpecification
{
   get { return HOps.IntToNullableBool( _InteractsWithDesktop_ ); }
}

public static void SpecifyInteractsWithDesktop()
{
   SpecifyInteractsWithDesktop( true );
}
public static void SpecifyInteractsWithDesktop(bool? value)
{
   _InteractsWithDesktop_ = HOps.NullableBoolToInt( value );
}

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

public static string EntryModuleName
{
   get
   {
      return Path.GetFileName( EntryModulePath );
   }
}

public static string EntryModulePath
{
   [MethodImpl(MethodImplOptions.NoInlining)]
   get
   {
      var entryAssembly =
         Assembly.GetEntryAssembly();
      return entryAssembly!=null ?
         entryAssembly.ManifestModule.FullyQualifiedName :
         Process.GetCurrentProcess().MainModule.FileName;
   }
}

public static string EntryModuleDirectory
{
   get
   {
      return Path.GetDirectoryName( EntryModulePath );
   }
}

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

static string ProcessModuleName
{
   [MethodImpl(MethodImplOptions.NoInlining)]
   get
   {
      return Process.GetCurrentProcess().MainModule.ModuleName;
   }
}

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

public static Version Version
{
   get { return Assembly.GetEntryAssembly().GetName().Version; }
}

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

[MethodImpl(MethodImplOptions.NoInlining)]
static int GetEntryPointArgCountFromCommandLine()
{
   return Environment.GetCommandLineArgs().Length - 1;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static string[] GetEntryPointArgsFromCommandLine()
{
   string[] arguments =
      Environment.GetCommandLineArgs();
   return arguments.Length > 1 ?
      HArray.Extract( arguments, 1 ) :
      new string[ 0 ];
}

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

public static string TempFolderPath
{
   get { return _TempFolderFullPath_ ?? Path.GetTempPath(); }
}

public static string TempFolderPathSpecification
{
   get { return _TempFolderPath_; }
}

public static void SpecifyTempFolderPath([HOptional] string value)
{
   _TempFolderFullPath_ = value!=null ? Path.GetFullPath( value ) : null;
   _TempFolderPath_ = value;
}

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

public static void PrepareTempFolder()
{
   PrepareTempFolder( TempFolderPath );
}

/// <exception cref="ArgumentNullException" />
public static void PrepareTempFolder(string path)
{
   HArgChecking.VerifyNotNull( path );
   Directory.CreateDirectory( path );
   SpecifyTempFolderPath( path );
}

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

static volatile int
   _IsProcessOwner_ = -1,
   _InteractsWithDesktop_ = -1;
static volatile string
   _TempFolderPath_, _TempFolderFullPath_;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HProgram
//**************************************************************************************************

} // CommonHelpers (.WASM)
