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

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

//**************************************************************************************************
/// <summary>
/// </summary>
public static partial class HDirectory {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="ArgumentNullException" />
public static bool CheckExists(string path,out Exception error)
{
   return HFile.CheckExists( path, true, out error );
}

/// <exception cref="ArgumentNullException" />
public static bool CheckNotExists(string path,out Exception error)
{
   return HFile.CheckNotExists( path, true, out error );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="HOperationFailedException" />
public static bool CheckIfExistsOrThrow(string path)
{
   return HFile.CheckIfExistsOrThrow( path, true );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
public static void VerifyExists(string path)
{
   HFile.VerifyExists( path, true );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
internal static void VerifyNotExists(string path)
{
   HFile.VerifyNotExists( path, true );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
public static bool ExamineIsReadonly(string path)
{
   return HFile.ExamineIsReadonly( path, true );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
public static void SetReadonlyAttribute(string path)
{
   HFile.SetReadonlyAttribute( path, true );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
public static void ResetReadonlyAttribute(string path)
{
   HFile.ResetReadonlyAttribute( path, true );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
public static FileAttributes GetAttributes(string path)
{
   return HFile.GetAttributes( path, true );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
public static void SetAttributes(string path,FileAttributes attributes)
{
   HFile.SetAttributes( path, true, attributes );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
public static FileAttributes AddAttributes(string path,FileAttributes attributes)
{
   return HFile.AddAttributes( path, true, attributes );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
public static FileAttributes RemoveAttributes(string path,FileAttributes attributes)
{
   return HFile.RemoveAttributes( path, true, attributes );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
public static FileAttributes ModifyAttributes( string path,
                                               FileAttributes attributesToAdd,
                                               FileAttributes attributesToRemove )
{
   return HFile.ModifyAttributes( path, true, attributesToAdd, attributesToRemove );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
public static void DeleteTree(string path)
{
   DeleteTree( path, false );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="HIncorrectFilePathException" />
public static void DeleteTree(string path,bool ignoreNotFoundError)
{
   DeleteTree( path,
      ignoreNotFoundError ?
      HFileDirDeletionOptions.IgnoreNotFoundError : 0 );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
public static void DeleteTree(string path,HFileDirDeletionOptions options)
{
   HFile.VerifyPath( path, true );

   bool ignoreNotFoundError =
      (options & HFileDirDeletionOptions.IgnoreNotFoundError) != 0;

   try { VerifyExists( path ); }
   catch (FileNotFoundException) {
      if (ignoreNotFoundError) return;
      throw HFile.CreateFileNotFoundException( path, true ); }

   string[]
      directories = Directory.GetDirectories( path, "*", SearchOption.AllDirectories ),
      files       = Directory.GetFiles      ( path, "*", SearchOption.AllDirectories );

   if ( (options & HFileDirDeletionOptions.RemoveReadonly) !=0 )
   {
      try { ResetReadonlyAttribute( path ); }
      catch (FileNotFoundException) {
         if (!ignoreNotFoundError) throw HFile.CreateFileNotFoundException( path, true ); }
      foreach (string directory in directories)
         try { ResetReadonlyAttribute( directory ); }
         catch (FileNotFoundException) {
            if (!ignoreNotFoundError) throw HFile.CreateFileNotFoundException( directory, true ); }
      foreach (string file in files)
         try { HFile.ResetReadonlyAttribute( file ); }
         catch (FileNotFoundException) {
            if (!ignoreNotFoundError) throw HFile.CreateFileNotFoundException( file, false ); }
   }
   else
   {
      try
      {
         if (ExamineIsReadonly( path ))
            throw HOpFailedExceptionCreator.Create( Verbose.FOLDER_IS_READONLY_0, path );
      }
      catch (FileNotFoundException) {
         if (!ignoreNotFoundError) throw HFile.CreateFileNotFoundException( path, true ); }
      foreach (string directory in directories)
         try
         {
            if (ExamineIsReadonly( directory ))
               throw HOpFailedExceptionCreator.Create(
                  Verbose.FOLDER_0_CONTAINS_READONLY_SUBFOLDER_1,
                  path, directory );
         }
         catch (FileNotFoundException) {
            if (!ignoreNotFoundError) throw HFile.CreateFileNotFoundException( directory, true ); }
      foreach (string file in files)
         try
         {
            if (HFile.ExamineIsReadonly( file ))
               throw HOpFailedExceptionCreator.Create(
                  Verbose.FOLDER_0_CONTAINS_READONLY_FILE_1,
                  path, file );
         }
         catch (FileNotFoundException) {
            if (!ignoreNotFoundError) throw HFile.CreateFileNotFoundException( file, false ); }
   }

   try { Directory.Delete( path, true ); }
   catch (FileNotFoundException) {
      if (!ignoreNotFoundError) throw HFile.CreateFileNotFoundException( path, true ); }
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
public static void DeleteReadonlyTree(string path)
{
   DeleteReadonlyTree( path, false );
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
public static void DeleteReadonlyTree(string path,bool ignoreNotFoundError)
{
   DeleteTree( path,
      HFileDirDeletionOptions.RemoveReadonly |
      ( ignoreNotFoundError ?
        HFileDirDeletionOptions.IgnoreNotFoundError : 0 ) );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="FileNotFoundException" />
/// <exception cref="HIncorrectFilePathException" />
/// <exception cref="HOperationFailedException" />
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Move(string sourcePath,string tragetPath)
{
   HFile.Move( sourcePath, tragetPath, true );
}

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

static HDirectory()
{
   CommonHelpers_Core.Access();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HDirectory
//**************************************************************************************************

} // CommonHelpers (.WASM)
