﻿using System.Collections.Generic;
using System.Text;
using EasyApi.Utils;
using EasyApi.Values;

namespace EasyApi.Metadata
{
	public abstract class MetadataItem : IMetadataItem
	{
		private static string BuildMetadataName(string metadataName, string metadataSubjectName, IMetadataItem parentMetadata)
		{
			var nameBuilder = new StringBuilder();
			if (parentMetadata != null)
			{
				nameBuilder.Append(parentMetadata.MetadataName);
				nameBuilder.Append(" => ");
			}

			nameBuilder.Append(metadataName);

			if (!string.IsNullOrEmpty(metadataSubjectName))
			{
				nameBuilder.Append("[");
				nameBuilder.Append(metadataSubjectName);
				nameBuilder.Append("]");
			}

			return nameBuilder.ToString();
		}

		protected MetadataItem(string metadataName, string metadataSubjectName, IMetadataItem parentMetadata, IEnumerable<ExtraProperty> properties)
		{
			Argument.IsNotNull(properties, nameof(properties));

			MetadataName = BuildMetadataName(metadataName, metadataSubjectName, parentMetadata);
			ParentMetadata = parentMetadata;
			// properties will use this during binding
			Properties = ReadOnlyExtraPropertyCollection.Empty;

			Properties = new ReadOnlyExtraPropertyCollection(BindProperties(properties));
		}

		private IEnumerable<ExtraProperty> BindProperties(IEnumerable<ExtraProperty> properties)
		{
			foreach (var extraProperty in properties)
			{
				if (extraProperty == null)
				{
					yield return null;
				}
				else
				{
					yield return extraProperty
						.Metadata
						.BindTo(this)
						.Create(extraProperty.Value);
				}
			}
		}

		public override string ToString()
		{
			return MetadataName;
		}

		public IMetadataItem ParentMetadata { get; }

		public IExtraPropertyCollection Properties { get; }

		public string MetadataName { get; }
	}
}