using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Paraiba.Collections.Generic;
using CoverageFramework.Operator.Generator;
using CoverageFramework.Operator.Selector;
using CoverageFramework.Model;
using CoverageFramework.Utility;
using Paraiba.Linq;

namespace CoverageFramework.Embedder
{
	public class SwitchCoverageEmbedder
	{
		private int _iSwitch;

		public void Embed(XElement root, IXElementRangeSelector switchRangeSelector, IXElementRangeSelector switchCaseRangeSelector, ITaggedXElementGenerator covGen, ITagger tagger, IDictionary<string, CoverageInfomation> covInfos)
		{
			switchRangeSelector.Select(root)
				.ForEach(switchBlock => {
					var switchPos = CodePositionUtil.CreateCodePosition(switchBlock);

					switchBlock.SelectMany(e_ => switchCaseRangeSelector.Select(e_))
						.ForEach((target, iCase) => {
							var targetList = target.ToList();
							var key = "switch," + (_iSwitch++) + ">" + iCase;
							var pos = CodePositionUtil.CreateCodePosition(targetList);
							covInfos[key] = new CoverageInfomation(switchPos, pos, tagger.Generate(targetList));

							targetList.Last().AddAfterSelf(covGen.Generate(key));
						});
				});
		}

		public void Embed(XElement root, IXElementSelector switchSelector, IXElementSelector switchCaseSelector, ITaggedXElementGenerator covGen, ITagger tagger, IDictionary<string, CoverageInfomation> covInfos)
		{
			switchSelector.Select(root)
				.ForEach(switchBlock => {
					var switchPos = CodePositionUtil.CreateCodePosition(switchBlock);

					switchCaseSelector.Select(switchBlock)
						.ForEach((target, iCase) => {
							var key = "switch," + (_iSwitch++) + ">" + iCase;
							var pos = CodePositionUtil.CreateCodePosition(target);
							covInfos[key] = new CoverageInfomation(switchPos, pos, tagger.Generate(target));

							target.AddAfterSelf(covGen.Generate(key));
						});
				});
		}
	}
}