using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.Extensions.Logging;

namespace Your.Namespace
{
	/// <summary>
	/// Convertor for <see cref="Exception" />s into <see cref="SaApiExceptionDetail" /> object.
	/// </summary>
	public interface IYourApiExceptionDetailConverter
	{
		/// <summary>
		/// Will convert an <see cref="Exception" /> into an <see cref="SaApiExceptionDetail" /> object.
		/// </summary>
		YourBussApiExceptionDetail Convert(Exception e);
	}

	/// <summary>
	/// Convertor for <see cref="Exception" />s into <see cref="SaApiExceptionDetail" /> object.
	/// </summary>
	public class YourBussApiExceptionDetailConverter : IYourBussApiExceptionDetailConverter
	{
		private ILogger<YourBussApiExceptionDetailConverter> _logger;

		public YourBussApiExceptionDetailConverter(ILogger<YourBussApiExceptionDetailConverter> logger)
		{
			_logger = logger;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal void LogConverting(Exception e)
		{
			_logger.LogDebug(
				$"Converting '{e.GetType().Name}' ({e.Message})",
				new { Type = e.GetType().Name, Message = e.Message }
			);
		}

		/// <inheritdoc />
		public YourBussApiExceptionDetail Convert(Exception e)
		{
			

			var result = new YourBussApiExceptionDetail();

			var currentException = e;
			var currentDetail = result;
			do
			{
				LogConverting(currentException);

				currentDetail.Message = currentException.Message;
				currentDetail.Type = currentException.GetType().AssemblyQualifiedName;
				currentDetail.StackTrace = currentException.StackTrace;
				currentDetail.InnerException = null;

				if (currentException.InnerException != null)
				{
					currentDetail.InnerException = new YourBussApiExceptionDetail();

					currentDetail = currentDetail.InnerException;
				}

				currentException = currentException.InnerException;
			} while (currentException != null);

			return result;
		}
	}
}