using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace MicronSync.Components
{
    public partial class WorkerUI : Form
    {
        public WorkerMode SetWorkerMode { get; internal set; }
        public enum WorkerMode
        {
            Backup,
            Restore
        }
        public LMZAParser.endResult _endResultLMZA = LMZAParser.endResult.Default;
        public CommonIO.endResult _endResultCIO = CommonIO.endResult.Default;
        private readonly UserConfig _userConfig = MainWindow._userConfig;
        private Stopwatch stopWatch = new Stopwatch();
        public TimeSpan compTime;

        public WorkerUI()
        {
            InitializeComponent();
        }

        #region Workers

        BackgroundWorker lmzaBackup = new BackgroundWorker();
        BackgroundWorker lmzaRestore = new BackgroundWorker();
        LMZAParser lmzaParser = new LMZAParser();

        private void LmzaBackup_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            canClose = true;
            Close();
        }

        private void LmzaBackup_DoWork(object sender, DoWorkEventArgs e)
        {
        _endResultLMZA = lmzaParser.MakePackage(
            Path.GetFileName(_userConfig.BackupDestination),
            _userConfig.BackupSource,
            Path.GetDirectoryName(_userConfig.BackupDestination),
            _userConfig.CompressionLevel,
            "",
            false);
        }

        private void LmzaRestore_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            canClose = true;
            Close();
        }

        private void LmzaRestore_DoWork(object sender, DoWorkEventArgs e)
        {
            // Process params.
            using (CommonIO cio = new CommonIO())
            {
                var restoreBackupDir = _userConfig.RestoreDestination + ".Backup";

                // Clear out old backup directory if it exists.
                if (_userConfig.OverwriteBackup && Directory.Exists(restoreBackupDir))
                {
                    Directory.Delete(restoreBackupDir, true);
                    Thread.Sleep(500); // Delay needed for reliability!
                }

                // Move source directory if also purging, otherwise perform standard copy.
                if (_userConfig.EnableBackup && !_userConfig.EnablePurge)
                {
                    _endResultCIO = cio.CopyEntireDirectory(
                        _userConfig.RestoreDestination,
                        restoreBackupDir);
                }
                else if (_userConfig.EnableBackup && _userConfig.EnablePurge)
                {
                    _endResultCIO = cio.RenameEntireDirectory(
                        _userConfig.RestoreDestination,
                        restoreBackupDir);
                    Directory.CreateDirectory(_userConfig.RestoreDestination);
                }

                if (_userConfig.EnablePurge)
                    _endResultCIO = cio.ClearEntireDirectory(_userConfig.RestoreDestination);
            }

            if (_endResultCIO == CommonIO.endResult.Default)
                _endResultLMZA = lmzaParser.ExtractPackage(
                    Path.GetFileName(_userConfig.RestoreSource),
                    Path.GetDirectoryName(_userConfig.RestoreSource),
                    _userConfig.RestoreDestination,
                    "");
        }

        #endregion

        #region Form Functionality

        private bool canClose;

        private void WorkerUI_Load(object sender, EventArgs e)
        {
            // Start stopwatch.
            stopWatch.Start();

            switch (SetWorkerMode)
            {
                case WorkerMode.Backup:
                    lmzaBackup.DoWork += LmzaBackup_DoWork;
                    lmzaBackup.RunWorkerCompleted += LmzaBackup_RunWorkerCompleted;
                    lmzaBackup.RunWorkerAsync();
                    break;
                case WorkerMode.Restore:
                    lmzaRestore.DoWork += LmzaRestore_DoWork;
                    lmzaRestore.RunWorkerCompleted += LmzaRestore_RunWorkerCompleted;
                    lmzaRestore.RunWorkerAsync();
                    break;
            }
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            lmzaParser.Abort();
        }

        private void WorkerUI_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Stop stopwatch.
            stopWatch.Stop();
            compTime = new TimeSpan(
                stopWatch.Elapsed.Hours,
                stopWatch.Elapsed.Minutes,
                stopWatch.Elapsed.Seconds);

            if (!canClose)
                e.Cancel = true;
            else
                e.Cancel = false;
        }

        #endregion

    }
}
