using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Paraiba.Linq;
using Paraiba.Xml.Linq;

namespace CoverageFramework.Operator.Selector.C2
{
	[Export(typeof(IXElementSelector))]
	public class ConditionalTermSelector : IXElementSelector
	{
		private static readonly string[] TargetNames = {
			"logical_or_expression",
			"logical_and_expression",
		};

		private static readonly string[] WithoutParentNames = {
			"postfix_expression",
		};

		public IEnumerable<XElement> Select(XElement root)
		{
			var targetParents = root.Descendants()
				.Where(e => TargetNames.Any(e.Name.LocalName.EndsWith))
				.Where(e => e.Elements().Count() >= 3)
				.Where(e => e.ParentsWhile(root)
					.Where(e2 => WithoutParentNames.Contains(e2.Name.LocalName))
					.All(e2 => e2.Elements().Count() == 1)
				);
			var targets = targetParents
				.SelectMany(e => e.Elements().OddIndexElements());

			// 他の項の要素を含まない項の要素のみを抽出
			// a == b && (a == c || a == d) => a == b, a == c, a == d
			var atomicTargets = targets.Independents().ToList();

			// XML要素の位置でソーティング
			atomicTargets.Sort((e1, e2) => e1.IsBefore(e2) ? -1 : 1);

			return atomicTargets;
		}
	}
}
