using System;
using System.IO;

using CommonHelpers;

namespace LnkConverter {

//**************************************************************************************************
partial class Program {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="OperationFailedException" />
/// <exception cref="ErrorLogException" />
static bool ProcessFile(string sourceFile,string targetFile)
{
   return ProcessFile( sourceFile, targetFile, false );
}

/// <exception cref="OperationFailedException" />
/// <exception cref="ErrorLogException" />
static bool ProcessFile(string sourceFile,string targetFile,bool copyInsteadOfConvert)
{
   bool succees = false;
   string targetFileTMP;
   switch ( ConvertDirection )
   {
   case ConvertDirection.LnkToTxt:
      targetFileTMP = TemporaryShortcutTxtFileName;
      break;
   case ConvertDirection.TxtToLnk:
      targetFileTMP = TemporaryShortcutLnkFileName;
      break;
   default:
      throw HAssertionFailure.DEAD_BRANCH();
   }
   switch ( ConversionMode )
   {
   case ConversionMode.SingleFile:
      CON.PrintOperation( true, HLocal.TEXT(
         "Conversion: \"{0}\" >> \"{1}\"",
         "Конвертация: \"{0}\" >> \"{1}\"" ),
         PathForPrint( sourceFile ), PathForPrint( targetFile ) );
      break;
   case ConversionMode.EntireFolder:
      CON.PrintOperation( HLocal.TEXT(
         "Processing: \"{0}\"{1}",
         "Обработка: \"{0}\"{1}" ),
         PathForPrint( sourceFile ),
         copyInsteadOfConvert ? HLocal.TEXT(" (copying)"," (копирование)") : "" );
      break;
   default:
      throw HAssertionFailure.DEAD_BRANCH();
   }
   try
   {
      try
      {
         EraseTemporaryShortcutFile( targetFileTMP );
         if ( copyInsteadOfConvert )
            try
            {
               File.Copy( AdducePath( sourceFile ), AdducePath( targetFileTMP ) );
            }
            catch (Exception e)
            {
               throw OpFailedExceptionCreator.Create( HLocal.TEXT(
                  "Can not copy file \"{0}\" to \"{1}\".\n"+
                  "{2}",
                  "Не удаётся скопировать файл \"{0}\" в \"{1}\".\n"+
                  "{2}" ),
                  PathForMessage( sourceFile ),
                  PathForMessage( targetFileTMP ),
                  e.Message );
            }
         else
         {
            ConversionWarningMessages.Clear();
            try
            {
               OpFailedExceptionTranslator.Do(delegate{
                  switch ( ConvertDirection )
                  {
                  case ConvertDirection.LnkToTxt:
                     LnkConverter.ConvertLnkToTxt( sourceFile, targetFileTMP );
                     break;
                  case ConvertDirection.TxtToLnk:
                     LnkConverter.ConvertTxtToLnk( sourceFile, targetFileTMP );
                     break;
                  }
               });
            }
            catch (OperationFailedException e)
            {
               throw OpFailedExceptionCreator.Create( HLocal.TEXT(
                  "Error during conversion of file \"{0}\" to \"{1}\".\n"+
                  "{2}",
                  "Ошибка при конвертации файла \"{0}\" в \"{1}\".\n"+
                  "{2}" ),
                  PathForMessage( sourceFile ),
                  PathForMessage( targetFile ),
                  e.Message );
            }
            if ( ConversionWarningMessages.Count > 0 )
               AddErrorLogWarningsRecord( sourceFile, ConversionWarningMessages.ToArray() );
         }
      }
      catch (OperationFailedException e)
      {
         try { File.Delete( AdducePath( targetFileTMP ) ); } catch {}
         throw OpFailedExceptionCreator.Create( e );
      }
      FileAttributes attr;
      try
      {
         attr = File.GetAttributes( AdducePath( sourceFile ) );
      }
      catch (Exception e)
      {
         throw OpFailedExceptionCreator.Create( HLocal.TEXT(
            "Can not obtain file attributes: \"{0}\".\n"+
            "{1}",
            "Не удаётся получить атрибуты файла: \"{0}\".\n"+
            "{1}" ), PathForMessage( sourceFile ), e.Message );
      }
      if ( !copyInsteadOfConvert )
         switch ( ConvertDirection )
         {
         case ConvertDirection.LnkToTxt: attr &= ~FileAttributes.ReadOnly; break;
         case ConvertDirection.TxtToLnk: attr |= FileAttributes.ReadOnly;  break;
         }
      try
      {
         File.SetAttributes( AdducePath( targetFileTMP ), attr );
      }
      catch (Exception e)
      {
         throw OpFailedExceptionCreator.Create( HLocal.TEXT(
            "Can not set file attributes: \"{0}\".\n"+
            "{1}",
            "Не удаётся установить атрибуты файла: \"{0}\".\n"+
            "{1}" ), PathForMessage( targetFileTMP ), e.Message );
      }
      try
      {
         HFile.Move( AdducePath( targetFileTMP ), AdducePath( targetFile ) );
      }
      catch (Exception e)
      {
         throw OpFailedExceptionCreator.Create( HLocal.TEXT(
            "Can not rename file \"{0}\" to \"{1}\".\n"+
            "{2}",
            "Не удаётся переименовать файл \"{0}\" в \"{1}\".\n"+
            "{2}" ),
            PathForMessage( targetFileTMP ),
            PathForMessage( targetFile ),
            e.Message );
      }
      _FilesSucceeded_++;
      succees = true;
   }
   catch (OperationFailedException e)
   {
      CON.PrintError( e.Message );
      AddErrorLogErrorRecord( sourceFile, e.Message );
      _FilesFailed_++;
   }
   _FilesPassed_++;
   return succees;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // Program
//**************************************************************************************************

} // LnkConverter
