public ConfigProfile Clone()
        {
            var clone = new ConfigProfile();

            clone.Name = this.Name;

            foreach (var profileName in this.ProfileNames)
            {
                clone.ProfileNames.Add(new ProfileNameValue(profileName.Value, profileName.OriginalValue)
                {
                    HasChanges = profileName.HasChanges
                });
            }
            clone.ProfileNames.HasChanges = this.ProfileNames.HasChanges;
            foreach (var alertType in this.AlertTypes)
            {
                clone.AlertTypes.Add(new AlertTypeValue(alertType.Value, alertType.OriginalValue)
                {
                    HasChanges = alertType.HasChanges
                });
            }
            clone.AlertTypes.HasChanges = this.AlertTypes.HasChanges;

            clone.DiscordWebhookUrl            = this.DiscordWebhookUrl;
            clone.DiscordBotName               = this.DiscordBotName;
            clone.DiscordUseTTS                = this.DiscordUseTTS;
            clone.PrefixMessageWithProfileName = this.PrefixMessageWithProfileName;
            clone.IsEnabled  = this.IsEnabled;
            clone.HasChanges = this.HasChanges;
            return(clone);
        }
        public void CopyFrom(ConfigProfile source)
        {
            if (source == null)
            {
                return;
            }

            try
            {
                this.BeginUpdate();

                this.Name = source.Name;

                this.ProfileNames.BeginUpdate();
                this.ProfileNames.Clear();
                foreach (var profileName in source.ProfileNames)
                {
                    this.ProfileNames.Add(new ProfileNameValue(profileName.Value, profileName.OriginalValue));
                }
                if (source.ProfileNames.HasChanges)
                {
                    this.ProfileNames.HasChanges = true;
                }
                this.ProfileNames.EndUpdate();

                this.AlertTypes.BeginUpdate();
                this.AlertTypes.Clear();
                foreach (var alertType in source.AlertTypes)
                {
                    this.AlertTypes.Add(new AlertTypeValue(alertType.Value, alertType.OriginalValue));
                }
                if (source.AlertTypes.HasChanges)
                {
                    this.AlertTypes.HasChanges = true;
                }
                this.AlertTypes.EndUpdate();

                this.DiscordWebhookUrl            = source.DiscordWebhookUrl;
                this.DiscordBotName               = source.DiscordBotName;
                this.DiscordUseTTS                = source.DiscordUseTTS;
                this.PrefixMessageWithProfileName = source.PrefixMessageWithProfileName;
                this.IsEnabled = source.IsEnabled;

                if (source.HasChanges)
                {
                    this.HasChanges = true;
                }
            }
            finally
            {
                this.EndUpdate();
            }
        }
        internal void HandleAlert(ConfigProfile configProfile, AlertType alertType, string profileName, string alertMessage)
        {
            if (configProfile == null || string.IsNullOrWhiteSpace(configProfile.DiscordWebhookUrl) || string.IsNullOrWhiteSpace(alertMessage))
            {
                return;
            }

            var postData = string.Empty;

            if (configProfile.DiscordUseTTS)
            {
                postData += $"&tts={configProfile.DiscordUseTTS}";
            }
            if (!string.IsNullOrWhiteSpace(configProfile.DiscordBotName))
            {
                postData += $"&username={configProfile.DiscordBotName.Replace("&", "_")}";
            }
            postData += $"&content=";
            if (configProfile.PrefixMessageWithProfileName && !string.IsNullOrWhiteSpace(profileName))
            {
                postData += $"({profileName.Replace("&", "_")}) ";
            }
            postData += $"{alertMessage.Replace("&", "_")}";

            if (postData.Length > MAX_MESSAGE_LENGTH)
            {
                postData = $"{postData.Substring(0, MAX_MESSAGE_LENGTH - 3)}...";
            }

            try
            {
                var data = Encoding.ASCII.GetBytes(postData);

                var url = configProfile.DiscordWebhookUrl;
                url = url.Trim();
                if (url.EndsWith("/"))
                {
                    url = url.Substring(0, url.Length - 1);
                }

                var httpRequest = WebRequest.Create($"{url}?wait=true");
                httpRequest.Timeout       = Config.Default.RequestTimeout;
                httpRequest.Method        = "POST";
                httpRequest.ContentType   = "application/x-www-form-urlencoded";
                httpRequest.ContentLength = data.Length;

                using (var stream = httpRequest.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }

                var httpResponse   = (HttpWebResponse)httpRequest.GetResponse();
                var responseString = new StreamReader(httpResponse.GetResponseStream()).ReadToEnd();
                if (httpResponse.StatusCode == HttpStatusCode.OK)
                {
                    Debug.WriteLine($"{nameof(HandleAlert)}\r\nResponse: {responseString}");
#if DEBUG
                    var logFile = Path.Combine(PluginHelper.PluginFolder, "DiscordSuccess.log");
                    File.AppendAllLines(logFile, new[] { $"{alertType}; {profileName} - {alertMessage.Replace(Environment.NewLine, " ")} ({responseString})" }, Encoding.Unicode);
#endif
                }
                else
                {
                    Debug.WriteLine($"{nameof(HandleAlert)}\r\n{httpResponse.StatusCode}: {responseString}");
#if DEBUG
                    var logFile = Path.Combine(PluginHelper.PluginFolder, "DiscordErrors.log");
                    File.AppendAllLines(logFile, new[] { $"{alertType}; {profileName} - {alertMessage.Replace(Environment.NewLine, " ")} ({responseString})" }, Encoding.Unicode);
#endif
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"ERROR: {nameof(HandleAlert)}\r\n{ex.Message}");
#if DEBUG
                var logFile = Path.Combine(PluginHelper.PluginFolder, "DiscordExceptions.log");
                File.AppendAllLines(logFile, new[] { $"{alertType}; {profileName} - {alertMessage.Replace(Environment.NewLine, " ")} ({ex.Message})" }, Encoding.Unicode);
#endif
            }
        }