using System.Linq;
using System.Xml.Linq;

namespace CoverageFramework.Etc
{
	public class ASTCleaner
	{
		public XDocument Clean(XDocument inputXDocument)
		{
			var outXDoc = new XDocument();
			var startElement = new XElement("cleanast");
			CreateElement(inputXDocument.Root, startElement);
			outXDoc.Add(startElement);
			return outXDoc;
		}

		protected virtual bool IsTerminalSymbol(XElement element)
		{
			return !element.HasElements;
		}

		private void CreateElement(XElement inElement, XElement outElement)
		{
			if (IsTerminalSymbol(inElement))
			{
				// 終端記号のノードの場合はそのまま出力
				outElement.Add(inElement);
			}
			else
			{
				var children = inElement.Elements().ToList();

				// 子の要素に終端記号が存在するか、子の要素が2個以上あるか
				if (children.Any(IsTerminalSymbol) || children.Count >= 2)
				{
					var element = new XElement(inElement.Name);
					foreach (var attr in inElement.Attributes())
					{
						element.SetAttributeValue(attr.Name, attr.Value);
					}
					foreach (var e in children)
					{
						CreateElement(e, element);
					}
					outElement.Add(element);
				}
				else
				{
					foreach (var e in children)
					{
						CreateElement(e, outElement);
					}
				}
			}
		}
	}
}