<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Forms;
using System.Diagnostics;

using NuGet;

using Duality.IO;
using Duality.Editor.Properties;
using Duality.Editor.Forms;

namespace Duality.Editor.PackageManagement
{
	public class PackageUpdateSchedule
	{
		private XDocument document;

		public PackageUpdateSchedule()
		{
			this.document = new XDocument(new XElement("UpdateConfig"));
		}

		public void AppendCopyFile(string copySource, string copyTarget)
		{
			// Remove previous deletion schedules referring to the copy target
			this.RemoveUpdateItems("Remove", copyTarget);

			// Append the copy entry
			this.document.Root.Add(new XElement("Update", 
				new XAttribute("source", copySource), 
				new XAttribute("target", copyTarget)));
		}
		public void AppendDeleteFile(string deleteTarget)
		{
			// Remove previous elements referring to the yet-to-delete file
			this.RemoveUpdateItems("Update", deleteTarget);
			this.RemoveUpdateItems("IntegrateProject", deleteTarget);

			// Append the delete entry
			this.document.Root.Add(new XElement("Remove", 
				new XAttribute("target", deleteTarget)));
		}
		public void AppendIntegrateProject(string projectFile, string solutionFile, string pluginDirectory)
		{
			// Remove previous deletion schedules referring to the copy target
			this.RemoveUpdateItems("Remove", projectFile);
			this.RemoveUpdateItems("Remove", solutionFile);
			this.RemoveUpdateItems("SeparateProject", solutionFile);

			// Append the integrate entry
			this.document.Root.Add(new XElement("IntegrateProject", 
				new XAttribute("project", projectFile), 
				new XAttribute("solution", solutionFile), 
				new XAttribute("pluginDirectory", pluginDirectory)));
		}
		public void AppendSeparateProject(string projectFile, string solutionFile)
		{
			this.RemoveUpdateItems("IntegrateProject", projectFile);

			// Append the integrate entry
			this.document.Root.Add(new XElement("SeparateProject", 
				new XAttribute("project", projectFile), 
				new XAttribute("solution", solutionFile)));
		}
		public void RemoveUpdateItems(string elementName, string referringTo)
		{
			IEnumerable<XElement> query = string.IsNullOrEmpty(elementName) ? 
				this.document.Root.Elements() : 
				this.document.Root.Elements(elementName);
			List<XElement> queryResults = query.ToList();

			foreach (XElement element in queryResults)
			{
				bool anyReference = false;
				foreach (XAttribute attribute in element.Attributes())
				{
					try
					{
						if (PathOp.ArePathsEqual(attribute.Value, referringTo))
						{
							anyReference = true;
							break;
						}
					}
					catch (Exception) {}
				}
				if (anyReference)
				{
					element.Remove();
				}
			}
		}
		
		/// <summary>
		/// Applies all changes that affect the Duality updater itself, which for that
		/// reason can't be done by the updater. The applied items will be removed from
		/// the schedule.
		/// </summary>
		/// <param name="updaterFilePath"></param>
		public void ApplyUpdaterChanges(string updaterFilePath)
		{
			List<XElement> updateItems = this.document.Root.Elements().ToList();
			foreach (XElement element in updateItems)
			{
				XAttribute attribTarget = element.Attribute("target");
				XAttribute attribSource = element.Attribute("source");
				string target = (attribTarget != null) ? attribTarget.Value : null;<commit_msg>PackageUpdateSchedule Testability #ADD: Added an abstraction leak to PakageUpdateSchedule allowing to access the scheduled update items directly, as this is probably the less maintenance-intensive way compared to introducing a while class hierarchy just for accessing them in tests only.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Forms;
using System.Diagnostics;

using NuGet;

using Duality.IO;
using Duality.Editor.Properties;
using Duality.Editor.Forms;

namespace Duality.Editor.PackageManagement
{
	public class PackageUpdateSchedule
	{
		public static readonly string CopyItem = "Update";
		public static readonly string DeleteItem = "Remove";
		public static readonly string IntegrateProjectItem = "IntegrateProject";
		public static readonly string SeparateProjectItem = "SeparateProject";

		private XDocument document;

		public IEnumerable<XElement> Items
		{
			get { return this.document.Root.Elements(); }
		}

		public PackageUpdateSchedule()
		{
			this.document = new XDocument(new XElement("UpdateConfig"));
		}

		public void AppendCopyFile(string copySource, string copyTarget)
		{
			// Remove previous deletion schedules referring to the copy target
			this.RemoveItems(DeleteItem, copyTarget);

			// Append the copy entry
			this.document.Root.Add(new XElement(CopyItem, 
				new XAttribute("source", copySource), 
				new XAttribute("target", copyTarget)));
		}
		public void AppendDeleteFile(string deleteTarget)
		{
			// Remove previous elements referring to the yet-to-delete file
			this.RemoveItems(CopyItem, deleteTarget);
			this.RemoveItems(IntegrateProjectItem, deleteTarget);

			// Append the delete entry
			this.document.Root.Add(new XElement(DeleteItem, 
				new XAttribute("target", deleteTarget)));
		}
		public void AppendIntegrateProject(string projectFile, string solutionFile, string pluginDirectory)
		{
			// Remove previous deletion schedules referring to the copy target
			this.RemoveItems(DeleteItem, projectFile);
			this.RemoveItems(DeleteItem, solutionFile);
			this.RemoveItems(SeparateProjectItem, solutionFile);

			// Append the integrate entry
			this.document.Root.Add(new XElement(IntegrateProjectItem, 
				new XAttribute("project", projectFile), 
				new XAttribute("solution", solutionFile), 
				new XAttribute("pluginDirectory", pluginDirectory)));
		}
		public void AppendSeparateProject(string projectFile, string solutionFile)
		{
			this.RemoveItems(IntegrateProjectItem, projectFile);

			// Append the integrate entry
			this.document.Root.Add(new XElement(SeparateProjectItem, 
				new XAttribute("project", projectFile), 
				new XAttribute("solution", solutionFile)));
		}
		private void RemoveItems(string itemType, string referringToFile)
		{
			IEnumerable<XElement> query = string.IsNullOrEmpty(itemType) ? 
				this.document.Root.Elements() : 
				this.document.Root.Elements(itemType);
			List<XElement> queryResults = query.ToList();

			foreach (XElement element in queryResults)
			{
				bool anyReference = false;
				foreach (XAttribute attribute in element.Attributes())
				{
					try
					{
						if (PathOp.ArePathsEqual(attribute.Value, referringToFile))
						{
							anyReference = true;
							break;
						}
					}
					catch (Exception) {}
				}
				if (anyReference)
				{
					element.Remove();
				}
			}
		}
		
		/// <summary>
		/// Applies all changes that affect the Duality updater itself, which for that
		/// reason can't be done by the updater. The applied items will be removed from
		/// the schedule.
		/// </summary>
		/// <param name="updaterFilePath"></param>
		public void ApplyUpdaterChanges(string updaterFilePath)
		{
			List<XElement> updateItems = this.document.Root.Elements().ToList();
			foreach (XElement element in updateItems)
			{
				XAttribute attribTarget = element.Attribute("target");
				XAttribute attribSource = element.Attribute("source");
				string target = (attribTarget != null) ? attribTarget.Value : null;
{'fraction_non_alphanumeric': 0.0991811938721606, 'fraction_numerical': 0.0, 'mean_word_length': 4.0996632996633, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6347178', 'n_tokens_mistral': 2472, 'n_tokens_neox': 2053, 'n_words': 561}