using System;
using System.IO;
using System.Collections.Generic;

using CommonHelpers;

namespace LnkConverter {

//**************************************************************************************************
static partial class Program {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static HConsole CON => HConsole.StdConIO;
//==================================================================================================

const string
   SyntaxSwitchKey               = "?",
   CheckVariablesSwitchKey       = "CKV",
   ExpandDollarVariablesSwitchKey= "XDV",
#if NLIB_USE
   ScreenCorruptionDemoSwitchKey = "SCRD",
#endif // NLIB_USE
   DVKeyArg_AllowEmptyValues     = "AllowEmptyValues",
   TemporaryShortcutLnkFileName  = "~shortcut_lnk.tmp",
   TemporaryShortcutTxtFileName  = "~shortcut_txt.tmp",
   ExeDummyShortcutFileName      = "LnkConverter.DummyShortcut.bin",
   FolderDummyShortcutFileName   = "LnkConverter.DummyShortcut.bin";

static readonly bool
   ReducedStartInfo = Environment.GetEnvironmentVariable( "LnkConverter.ReducedStartInfo" ) == "1",
   AvoidLongPaths   = Environment.GetEnvironmentVariable( "LnkConverter.AvoidLongPaths"   ) == "1";

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

/// <exception cref="InvalidOperationException" />
static HLnkConverter LnkConverter
{
   get {
      if ( _LnkConverter_ == null )
         throw HInvOpExceptionCreator.InvalidStaticOperation;
      return _LnkConverter_; }
}

static bool CheckEnviromnentVariables
{
   get { return HFlags.Check( _TxtFlags_, HLnkConverterTxtFlags.CheckVariables ); }
}
static bool ExpandDollarVariables
{
   get { return HFlags.Check( _TxtFlags_, HLnkConverterTxtFlags.ExpandDollarVariables ); }
}

static bool IsSyntaxSwitchSpecified
{
   get { return _IsSyntaxSwitchSpecified_; }
}

static bool ExeDummyShortcutFromCurrentDirUsage
{
   get { return _ExeDummyShortcutFromCurrentDirUsage_; }
}
static bool FolderDummyShortcutFromCurrentDirUsage
{
   get { return _FolderDummyShortcutFromCurrentDirUsage_; }
}

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

static string SourceName   { get { return _SourceName_;  } }
static string TargetName   { get { return _TargetName_;  } }
static string TempName     { get { return _TempName_;    } }

static ConvertDirection ConvertDirection  { get { return _ConvertDirection_; } }
static ConversionMode   ConversionMode    { get { return _ConversionMode_; } }

static int FilesPassed     { get { return _FilesPassed_;    } }
static int FilesSucceeded  { get { return _FilesSucceeded_; } }
static int FilesFailed     { get { return _FilesFailed_;    } }

static List<string> ConversionWarningMessages { get { return _ConversionWarningMessages_; } }

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

/// <exception cref="ArgumentNullException" />
static string AdducePath(string path)
{
   HArgChecking.VerifyNotNull( path );
   return _UseLongPaths_ ? HPath.ToLong( path ) : path;
}

static string PathForMessage(string path)
{
   return HPath.WithoutLongNamePrefix( path );
}
static string PathForPrint(string path)
{
   return HPath.GetRelativePathIfPossible( path, true );
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="OperationFailedException" />
static void HandleCheckFileExistsError(string fileName,Exception error)
{
   HArgChecking.VerifyNotNulls( fileName, error );
   if ( !(error is FileNotFoundException) )
      throw OpFailedExceptionCreator.Create( HLocal.TEXT(
         "Can not check file existence: \"{0}\".\n"+
         "{1}",
         "Не удаётся проверить наличие файла: \"{0}\".\n"+
         "{1}" ), fileName, error.Message );
}

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

/// <exception cref="OperationFailedException" />
static void EraseTemporaryShortcutFile(string fileName)
{
   Exception error;
   if ( HFile.CheckExists( AdducePath( fileName ), out error ) )
   {
      try
      {
         File.Delete( AdducePath( fileName ) );
      }
      catch (Exception e)
      {
         throw OpFailedExceptionCreator.Create( HLocal.TEXT(
            "Can not remove temporary file: \"{0}\".\n"+
            "{1}",
            "Не удаётся удалить временный файл: \"{0}\".\n"+
            "{1}" ), fileName, e.Message );
      }
   }
   else
      HandleCheckFileExistsError( fileName, error );
}

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

public static void Escape()
{
   EscapeErrorLog();
}

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

static Program()
{
   _UseLongPaths_ = !AvoidLongPaths && HOperatingSystem.IsWindows81orLater;
}

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

static readonly bool
   _UseLongPaths_;

static HLnkConverterTxtFlags
   _TxtFlags_;
static HLnkConverter
   _LnkConverter_;

static bool
   _IsSyntaxSwitchSpecified_,
   _ExeDummyShortcutFromCurrentDirUsage_,
   _FolderDummyShortcutFromCurrentDirUsage_;

static string
   _SourceName_,
   _TargetName_,
   _TempName_;

static ConvertDirection
   _ConvertDirection_;
static ConversionMode
   _ConversionMode_;

static List<string>
   _ConversionWarningMessages_ = new List<string>();

static int
   _FilesPassed_,
   _FilesSucceeded_,
   _FilesFailed_;
/*
static List<DictionaryEntry>
   _EnvironmentToRestore_;
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // Program
//**************************************************************************************************

} // LnkConverter
