using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

#pragma warning disable CS8604 // Possible null reference argument.
namespace EasyDevCore.Common
{
    /// <summary>
    /// 
    /// </summary>
    public static class ExceptionHelper
    {
        /// <summary>
        /// Gets the stack trace of exception.
        /// </summary>
        /// <param name="ex">The ex.</param>
        /// <param name="msg">The MSG.</param>
        private static void GetExceptionStackTrace(Exception ex, ref StringBuilder msg)
        {
            msg.Append(ex.StackTrace);
            if (ex.InnerException != null)
            {
                msg.AppendLine(ex.InnerException.Message);
                GetExceptionStackTrace(ex.InnerException, ref msg);
            }
        }

        /// <summary>
        /// Gets the stack trace of exception.
        /// </summary>
        /// <param name="ex">The ex.</param>
        /// <returns></returns>
        private static string GetExceptionStackTrace(Exception ex)
        {
            StringBuilder msg = new StringBuilder();
            GetExceptionStackTrace(ex, ref msg);
            return msg.ToString();
        }


        /// <summary>
        /// Gets the exception info.
        /// </summary>
        /// <param name="exception">The exception.</param>
        /// <returns></returns>
        public static string GetMessagesDetail(this Exception exception)
        {
            if (exception != null)
            {
                StringBuilder buidler = new StringBuilder();
                buidler.AppendLine(string.Format("---- Begin of Exception -----", exception.Message));
                buidler.AppendLine(string.Format("+ Message : {0}", exception.Message));
                buidler.AppendLine(string.Format("+ Source : {0}", exception.Source));
                buidler.AppendLine(string.Format("+ Stack : {0}", exception.StackTrace));
                buidler.AppendLine(string.Format("+ Target : {0}", (exception.TargetSite == null ? "?" : exception.TargetSite.ToString())));
                buidler.AppendLine(string.Format("+ Helplink : {0}", exception.HelpLink));
                buidler.AppendLine("+ Stack : ");
                buidler.AppendLine("----- Begin of exception stack -----");
                buidler.AppendLine(GetExceptionStackTrace(exception));
                buidler.AppendLine("----- End of exception stack -----");
                if (exception.Data != null && exception.Data.Keys.Count > 0)
                {
                    buidler.AppendLine("----- Begin of exception data info  -----");
                    foreach (var key in exception.Data.Keys)
                    {
                        buidler.AppendLine(string.Format(">>>>>>>>>> [{0}] <<<<<<<<<<", key));
                        buidler.AppendLine(string.Format("{0}", exception.Data[key]));
                        buidler.AppendLine(string.Format("^^^^^^^^^^ [{0}] ^^^^^^^^^^", key));

                        buidler.AppendLine(string.Format("---- End of Exception -----", exception.Message));

                    }
                    buidler.AppendLine("----- End of exception data info  -----");
                }
                buidler.AppendLine(string.Format("---- End of Exception -----", exception.Message));
                return buidler.ToString();
            }
            return string.Empty;
        }
    }
}
