using System.Collections.Generic;
using System.Text;

namespace LocalizerGenerator
{
	class LocalizerBuilder
	{
		public string Name { get; set; }
		public string ClassName => $"{Name}Localizer";
		public string InterfaceName => $"I{Name}Localizer";
		public string Namespace { get; set; }
		public List<string> Properties { get; } = new List<string>();
		public string IStringLocalizerName => $"IStringLocalizer<{ClassName}>";
		public string BaseClassName => $"DelegatingStringLocalizer<{ClassName}>";

		public string BuildSource()
		{
			var builder = new StringBuilder();
			BuildNamespace(builder);
			return builder.ToString();
		}

		void BuildNamespace(StringBuilder builder)
		{
			builder.Append("namespace ").Append(Namespace).Append(" {").AppendLine();
			BuildUsings(builder);
			BuildInterface(builder);
			BuildClass(builder);
			builder.AppendLine("}");
		}

		void BuildUsings(StringBuilder builder)
		{
			builder.AppendLine("using Microsoft.Extensions.Localization;");
			builder.AppendLine("using Havit.Blazor.Components.Web.Infrastructure;");
		}

		void BuildInterface(StringBuilder builder)
		{
			builder.Append("public interface ").Append(InterfaceName).Append(" : ").Append(IStringLocalizerName).Append(" {").AppendLine();
			foreach (var property in Properties)
			{
				builder.Append("LocalizedString ").Append(property).Append(" { get; }").AppendLine();
			}
			builder.AppendLine("}");
		}

		void BuildClass(StringBuilder builder)
		{
			builder.Append("public class ").Append(ClassName).Append(" : ").Append(BaseClassName).Append(", ").Append(InterfaceName).Append(" {").AppendLine();
			BuildCtor(builder);
			foreach (var property in Properties)
			{
				builder.Append("public LocalizedString ").Append(property).Append(" => this[\"").Append(property).Append("\"];").AppendLine();
			}
			builder.AppendLine("}");
		}

		void BuildCtor(StringBuilder builder)
		{
			builder.Append("public ").Append(ClassName).Append("(").Append(IStringLocalizerName).Append(" innerLocalizer) : base(innerLocalizer) { }").AppendLine();
		}
	}
}
