using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace GFATask
{
    /// <summary>
    /// Eine Klasse die Werkzeuge zum Umgang mit den benötigten Programm-Dateien besitzt. Darunter Sicherungs-, Vorlagen- und Überschreibfunktionen
    /// </summary>
    public class Deploy
    {
        /// <summary>
        /// Erzeugt am gewünschten Ort eine neue Datei aus dem Vorlagentypen und überschreibt diese, falls bereits vorhanden. 
        /// Bei Bedarf kann zuvor eine Sicherung dieser Datei mit Datumsangabe erstellt werden. Kann auch als reine Backup-Funktion genutzt werden.
        /// Sofern die Datei bereits vorhanden ist, kann die Variable overwrite auf "false" und dobackup auf "true" gesetzt werden.
        /// </summary>
        /// <param name="type">Gibt den Vorlagentypen an der erzeugt werden soll</param>
        /// <param name="target">Ist der gewünschte Pfad, an dem die Vorlage abgelegt wird</param>
        /// <param name="overwrite">Sofern bereits eine Datei mit diesem Namen vorhanden ist, wird diese überschrieben</param>
        /// <param name="dobackup">Gibt an, ob eine Sicherung der Datei erstellt werden soll</param>
        /// <returns></returns>
        public static bool Templating(Type type, string target, bool overwrite, bool dobackup)
        {
            var action = new Action(delegate
            {
                object o = Activator.CreateInstance(type);
                JSON.Serialize(o, target);
            });

            if (File.Exists(target))
            {
                if (dobackup)
                {
                    string filename = Path.GetFileNameWithoutExtension(target);
                    string bak_datetime = DateTime.Now.ToString("yyyyMMdd-HHmmss");
                    File.Copy(target, $@"{Paths.Bak.Directory}\{Environment.UserName.ToLower()}_{bak_datetime}_{filename}.bak");
                    Log.EventLog.Write($"{filename} Backup erstellt", LogClassification.Success);
                }
                if (overwrite)
                {
                    try
                    {
                        string filename = Path.GetFileName(target);
                        string overwrite_datetime = DateTime.Now.ToString("yyyyMMdd-HHmmss");
                        Log.EventLog.Write($"{filename} überschrieben", LogClassification.Success);
                        action.Invoke();
                        return true;
                    }
                    catch (Exception ex)
                    {
                        Log.EventLog.Write("Vorlage nicht erstellt", LogClassification.Crash, ex);
                        return false;
                    }
                }
                return false;
            }
            else
            {
                try
                {
                    action.Invoke();
                    return true;
                }
                catch (Exception ex)
                {
                    Log.EventLog.Write("Vorlage nicht erstellt", LogClassification.MediumError, ex);
                    return false;
                }
            }
        }



        /// <summary>
        /// Erzeugt im benutzerdefinierten Pfad (%APPDATA%\GFATASK) eine leere Typendatei. Kann auch als reine Backup-Funktion genutzt werden.
        /// Sofern die Datei bereits vorhanden ist, kann die Variable overwrite auf "false" und dobackup auf "true" gesetzt werden.
        /// </summary>
        /// <param name="deploytype">Gibt den Typen der AppList an</param>
        /// <param name="overwrite">Soll die Datei überschrieben werden</param>
        /// <param name="dobackup">Soll eine Sicherung der Datei erzeugt werden</param>
        /// <returns></returns>
        public static bool AppListTemplate(DeployAppList deploytype, bool overwrite, bool dobackup)
        {
            string targetpath = deploytype == DeployAppList.Prevalence ? Paths.Prevalence.FullName : Paths.Favorites.Apps.FullName;
            var action = new Func<bool>(delegate
            {
                try
                {
                    string path = string.Empty;
                    var list = new object();
                    if (deploytype == DeployAppList.Prevalence)
                    {
                        list = new Models.Prevalence()
                        {
                            Admin = new List<Models.Prevalence.AppPrevalenceProperties>(),
                            Citrix = new List<Models.Prevalence.AppPrevalenceProperties>(),
                            Favorites = new List<Models.Prevalence.AppPrevalenceProperties>(),
                            Menu = new List<Models.Prevalence.AppPrevalenceProperties>(),
                            User = new List<Models.Prevalence.AppPrevalenceProperties>()
                        };
                    }
                    else
                    {
                        list = new Models.AppList<Models.App>() { Apps = new List<Models.App>(), Type = AppType.Favorites };
                    }
                    JSON.Serialize(list, targetpath);
                    return true;
                }
                catch (Exception ex)
                {
                    Log.EventLog.Write("Vorlage nicht erstellt", LogClassification.MediumError, ex);
                    return false;
                }
            });

            if (File.Exists(targetpath))
            {
                if (dobackup)
                {
                    string filename = Path.GetFileNameWithoutExtension(targetpath);
                    string bak_datetime = DateTime.Now.ToString("yyyyMMdd-HHmmss");
                    File.Copy(targetpath, $@"{Paths.Bak.Directory}\{Environment.UserName.ToLower()}_{bak_datetime}_{filename}.bak");
                    Config.User.Deploy.Backup = false;
                }
                if (overwrite)
                {
                    Config.User.Deploy.Overwrite = false;
                    return action.Invoke();
                }
                if(dobackup || overwrite)
                    JSON.Save(JSONConfig.User);
                return false;
            }
            else
            {
                return action.Invoke();
            }
        }
    }



    /// <summary>
    /// Definiert die zu erzeugenden Listen
    /// </summary>
    public enum DeployAppList
    {
        /// <summary>
        /// Definiert die Prevalence-(Beliebtheits)-Datei
        /// </summary>
        Prevalence = 0,

        /// <summary>
        /// Definiert die Favoriten-Datei
        /// </summary>
        Favorites = 1
    }
}
