<commit_before>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;

using UnityEngine;
using KSP;
using KSPPluginFramework;

namespace KerbalAlarmClock
{
    internal static class KACUtils
    {
        //public static String AppPath = KSPUtil.ApplicationRootPath.Replace("\\", "/");
        //public static String PlugInPath = AppPath + "PluginData/KerbalAlarmClock/";
        internal static String PathApp = KSPUtil.ApplicationRootPath.Replace("\\", "/");
        internal static String PathTriggerTech = string.Format("{0}GameData/TriggerTech", PathApp);

        internal static String PathPlugin = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        internal static String PathPluginData = string.Format("{0}/PluginData/Data", PathPlugin);
        internal static String PathTextures = string.Format("{0}/PluginData/Textures", PathPlugin);
        internal static String PathToolbarIcons = string.Format("{0}/ToolbarIcons", PathPlugin);
        internal static String PathPluginSounds = string.Format("{0}/Sounds", PathPlugin);

        internal static String DBPathTriggerTech = string.Format("TriggerTech");
        internal static String DBPathPlugin = string.Format("TriggerTech/{0}", KerbalAlarmClock._AssemblyName);
        //internal static String DBPathToolbarIcons = string.Format("{0}/ToolbarIcons", DBPathPlugin);
        //internal static String DBPathTextures = string.Format("{0}/Textures", DBPathPlugin);
        internal static String DBPathPluginSounds = string.Format("{0}/Sounds", DBPathPlugin);

        internal static String PathToolbarTexturePath = PathToolbarIcons.Replace("\\", "/").Substring(PathToolbarIcons.Replace("\\", "/").ToLower().IndexOf("/gamedata/") + 10);

        internal static String SavePath;

        internal static Boolean BackupSaves()
        {
            if (!KerbalAlarmClock.settings.BackupSaves)
            {
                return true;
            }

            Boolean blnReturn=false;
            MonoBehaviourExtended.LogFormatted("Backing up saves");

            if (!System.IO.Directory.Exists(SavePath))
            {
                MonoBehaviourExtended.LogFormatted("Saves Path not found: {0}");
            }
            else
            {
                if (!System.IO.File.Exists(String.Format("{0}/persistent.sfs", SavePath)))
                {
                    MonoBehaviourExtended.LogFormatted("Persistent.sfs file not found: {0}/persistent.sfs", SavePath);
                }
                else
                {
                    try
                    {
                        System.IO.File.Copy(String.Format("{0}/persistent.sfs", SavePath),
                                            String.Format("{0}/zKACBACKUP{1:yyyyMMddHHmmss}-persistent.sfs", SavePath, DateTime.Now),
                                            true);
                        MonoBehaviourExtended.LogFormatted("Backed Up Persistent.sfs as: {0}/zKACBACKUP{1:yyyyMMddHHmmss}-persistent.sfs", SavePath, DateTime.Now);
                        
                        //Now go for the quicksave
                        if (System.IO.File.Exists(String.Format("{0}/quicksave.sfs", SavePath)))
                        {
                            System.IO.File.Copy(String.Format("{0}/quicksave.sfs", SavePath),
                                                String.Format("{0}/zKACBACKUP{1:yyyyMMddHHmmss}-quicksave.sfs", SavePath, DateTime.Now),
                                                true);
                            MonoBehaviourExtended.LogFormatted("Backed Up quicksave.sfs as: {0}/zKACBACKUP{1:yyyyMMddHHmmss}-quicksave.sfs", SavePath, DateTime.Now);
                        }                        
                        blnReturn = true;

                        PurgeOldBackups();

                    }
                    catch (Exception ex)
                    {
                        MonoBehaviourExtended.LogFormatted("Unable to backup: {0}/persistent.sfs\r\n\t{1}", SavePath,ex.Message);
                    }
                }
            }

            return blnReturn;
        }

        private static void PurgeOldBackups()
        {
            PurgeOldBackups("persistent.sfs");
            PurgeOldBackups("quicksave.sfs");
        }

        private static void PurgeOldBackups(String OriginalName)
        {
            //Now delete any old ones greater than the list to keep
            List<System.IO.FileInfo> SaveBackups = new System.IO.DirectoryInfo(SavePath).GetFiles(string.Format("KACBACKUP*{0}",OriginalName)).ToList<System.IO.FileInfo>();
            SaveBackups.AddRange(new System.IO.DirectoryInfo(SavePath).GetFiles(string.Format("zKACBACKUP*{0}", OriginalName)).ToList<System.IO.FileInfo>());

            MonoBehaviourExtended.LogFormatted("{0} KACBackup...{1} Saves found", SaveBackups.Count,OriginalName);

            List<System.IO.FileInfo> SaveBackupsToDelete = SaveBackups.OrderByDescending(fi => fi.CreationTime).Skip(KerbalAlarmClock.settings.BackupSavesToKeep).ToList<System.IO.FileInfo>();
            MonoBehaviourExtended.LogFormatted("{0} KACBackup...{1} Saves to purge", SaveBackupsToDelete.Count, OriginalName);
            for (int i = SaveBackupsToDelete.Count - 1; i >= 0; i--)
            {
                MonoBehaviourExtended.LogFormatted("\tDeleting {0}", SaveBackupsToDelete[i].Name);

                //bin the loadmeta if it exists too
                string loadmetaFile = SaveBackupsToDelete[i].DirectoryName + "/" + System.IO.Path.GetFileNameWithoutExtension(SaveBackupsToDelete[i].FullName) + ".loadmeta";
                if (System.IO.File.Exists(loadmetaFile))
                {
                    System.IO.File.Delete(loadmetaFile);
                }

                SaveBackupsToDelete[i].Delete();
            }
        }

        //generic function
        internal static String PipeSepVariables(params object[] vars)
        {
            return SepVariables("|", vars);
        }

        internal static String CommaSepVariables(params object[] vars)
        {
            return SepVariables(",", vars);
        }

        internal static String SepVariables(String separator, params object[] vars)
        {
            String strReturn = "";
            foreach (object tmpVar in vars)
            {
                if (strReturn != "") strReturn += separator;
                if (tmpVar == null)
                    strReturn += "";
                else
                {
                    strReturn = EncodeVarStrings(strReturn);
                    strReturn += tmpVar.ToString();
                }
            }
            return strReturn;
        }

        internal static String EncodeVarStrings(String Input)
        {
            String strReturn = Input;
            //encode \r\t\n
            strReturn = strReturn.Replace("\r", "\\r");
            strReturn = strReturn.Replace("\n", "\\n");
            strReturn = strReturn.Replace("\t", "\\t");
            return strReturn;
        }

        internal static String DecodeVarStrings(String Input)
        {
            String strReturn = Input;
            //encode \r\t\n
            strReturn = strReturn.Replace("\\r", "\r");
            strReturn = strReturn.Replace("\\n", "\n");
            strReturn = strReturn.Replace("\\t", "\t");
            return strReturn;
        }

        //public static Byte[] LoadFileToArray(String Filename)
        //{
        //    Byte[] arrBytes;

        //    arrBytes = KSP.IO.File.ReadAllBytes<KerbalAlarmClock>(Filename);

        //    return arrBytes;
        //}

        //public static void SaveFileFromArray(Byte[] data, String Filename)<commit_msg>Force line-breaks in comment when loading/saving alarms<commit_after>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;

using UnityEngine;
using KSP;
using KSPPluginFramework;

namespace KerbalAlarmClock
{
    internal static class KACUtils
    {
        //public static String AppPath = KSPUtil.ApplicationRootPath.Replace("\\", "/");
        //public static String PlugInPath = AppPath + "PluginData/KerbalAlarmClock/";
        internal static String PathApp = KSPUtil.ApplicationRootPath.Replace("\\", "/");
        internal static String PathTriggerTech = string.Format("{0}GameData/TriggerTech", PathApp);

        internal static String PathPlugin = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        internal static String PathPluginData = string.Format("{0}/PluginData/Data", PathPlugin);
        internal static String PathTextures = string.Format("{0}/PluginData/Textures", PathPlugin);
        internal static String PathToolbarIcons = string.Format("{0}/ToolbarIcons", PathPlugin);
        internal static String PathPluginSounds = string.Format("{0}/Sounds", PathPlugin);

        internal static String DBPathTriggerTech = string.Format("TriggerTech");
        internal static String DBPathPlugin = string.Format("TriggerTech/{0}", KerbalAlarmClock._AssemblyName);
        //internal static String DBPathToolbarIcons = string.Format("{0}/ToolbarIcons", DBPathPlugin);
        //internal static String DBPathTextures = string.Format("{0}/Textures", DBPathPlugin);
        internal static String DBPathPluginSounds = string.Format("{0}/Sounds", DBPathPlugin);

        internal static String PathToolbarTexturePath = PathToolbarIcons.Replace("\\", "/").Substring(PathToolbarIcons.Replace("\\", "/").ToLower().IndexOf("/gamedata/") + 10);

        internal static String SavePath;

        internal static Boolean BackupSaves()
        {
            if (!KerbalAlarmClock.settings.BackupSaves)
            {
                return true;
            }

            Boolean blnReturn=false;
            MonoBehaviourExtended.LogFormatted("Backing up saves");

            if (!System.IO.Directory.Exists(SavePath))
            {
                MonoBehaviourExtended.LogFormatted("Saves Path not found: {0}");
            }
            else
            {
                if (!System.IO.File.Exists(String.Format("{0}/persistent.sfs", SavePath)))
                {
                    MonoBehaviourExtended.LogFormatted("Persistent.sfs file not found: {0}/persistent.sfs", SavePath);
                }
                else
                {
                    try
                    {
                        System.IO.File.Copy(String.Format("{0}/persistent.sfs", SavePath),
                                            String.Format("{0}/zKACBACKUP{1:yyyyMMddHHmmss}-persistent.sfs", SavePath, DateTime.Now),
                                            true);
                        MonoBehaviourExtended.LogFormatted("Backed Up Persistent.sfs as: {0}/zKACBACKUP{1:yyyyMMddHHmmss}-persistent.sfs", SavePath, DateTime.Now);
                        
                        //Now go for the quicksave
                        if (System.IO.File.Exists(String.Format("{0}/quicksave.sfs", SavePath)))
                        {
                            System.IO.File.Copy(String.Format("{0}/quicksave.sfs", SavePath),
                                                String.Format("{0}/zKACBACKUP{1:yyyyMMddHHmmss}-quicksave.sfs", SavePath, DateTime.Now),
                                                true);
                            MonoBehaviourExtended.LogFormatted("Backed Up quicksave.sfs as: {0}/zKACBACKUP{1:yyyyMMddHHmmss}-quicksave.sfs", SavePath, DateTime.Now);
                        }                        
                        blnReturn = true;

                        PurgeOldBackups();

                    }
                    catch (Exception ex)
                    {
                        MonoBehaviourExtended.LogFormatted("Unable to backup: {0}/persistent.sfs\r\n\t{1}", SavePath,ex.Message);
                    }
                }
            }

            return blnReturn;
        }

        private static void PurgeOldBackups()
        {
            PurgeOldBackups("persistent.sfs");
            PurgeOldBackups("quicksave.sfs");
        }

        private static void PurgeOldBackups(String OriginalName)
        {
            //Now delete any old ones greater than the list to keep
            List<System.IO.FileInfo> SaveBackups = new System.IO.DirectoryInfo(SavePath).GetFiles(string.Format("KACBACKUP*{0}",OriginalName)).ToList<System.IO.FileInfo>();
            SaveBackups.AddRange(new System.IO.DirectoryInfo(SavePath).GetFiles(string.Format("zKACBACKUP*{0}", OriginalName)).ToList<System.IO.FileInfo>());

            MonoBehaviourExtended.LogFormatted("{0} KACBackup...{1} Saves found", SaveBackups.Count,OriginalName);

            List<System.IO.FileInfo> SaveBackupsToDelete = SaveBackups.OrderByDescending(fi => fi.CreationTime).Skip(KerbalAlarmClock.settings.BackupSavesToKeep).ToList<System.IO.FileInfo>();
            MonoBehaviourExtended.LogFormatted("{0} KACBackup...{1} Saves to purge", SaveBackupsToDelete.Count, OriginalName);
            for (int i = SaveBackupsToDelete.Count - 1; i >= 0; i--)
            {
                MonoBehaviourExtended.LogFormatted("\tDeleting {0}", SaveBackupsToDelete[i].Name);

                //bin the loadmeta if it exists too
                string loadmetaFile = SaveBackupsToDelete[i].DirectoryName + "/" + System.IO.Path.GetFileNameWithoutExtension(SaveBackupsToDelete[i].FullName) + ".loadmeta";
                if (System.IO.File.Exists(loadmetaFile))
                {
                    System.IO.File.Delete(loadmetaFile);
                }

                SaveBackupsToDelete[i].Delete();
            }
        }

        //generic function
        internal static String PipeSepVariables(params object[] vars)
        {
            return SepVariables("|", vars);
        }

        internal static String CommaSepVariables(params object[] vars)
        {
            return SepVariables(",", vars);
        }

        internal static String SepVariables(String separator, params object[] vars)
        {
            String strReturn = "";
            foreach (object tmpVar in vars)
            {
                if (strReturn != "") strReturn += separator;
                if (tmpVar == null)
                    strReturn += "";
                else
                {
                    strReturn = EncodeVarStrings(strReturn);
                    strReturn += tmpVar.ToString();
                }
            }
            return strReturn;
        }

        internal static String EncodeVarStrings(String Input)
        {
            String strReturn = Input;
            //encode \r\t\n
            strReturn = strReturn.Replace("\r\n", "\\r\\n");
            strReturn = strReturn.Replace("\r", "\\r");
            strReturn = strReturn.Replace("\n", "\\n");
            strReturn = strReturn.Replace("\t", "\\t");
            return strReturn;
        }

        internal static String DecodeVarStrings(String Input)
        {
            String strReturn = Input;
            //encode \r\t\n
            strReturn = strReturn.Replace("\\r\\n", "\r\n");
            strReturn = strReturn.Replace("\\r", "\r\n");
            strReturn = strReturn.Replace("\\n", "\n");
            strReturn = strReturn.Replace("\\t", "\t");
            return strReturn;
        }

        //public static Byte[] LoadFileToArray(String Filename)
        //{
        //    Byte[] arrBytes;

        //    arrBytes = KSP.IO.File.ReadAllBytes<KerbalAlarmClock>(Filename);

        //    return arrBytes;
        //}

        //public static void SaveFileFromArray(Byte[] data, String Filename)
{'fraction_non_alphanumeric': 0.1137979182533638, 'fraction_numerical': 0.00456968773800457, 'mean_word_length': 1.8848407176858293, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4379864', 'n_tokens_mistral': 4214, 'n_tokens_neox': 4033, 'n_words': 765}