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

namespace DFS.Core.Mvc.CodeGenerate
{
    /// <summary>
    /// 模版
    /// </summary>
    public static class ExceptionTemp
    {
        /// <summary>
        /// 业务异常类
        /// </summary>
        /// <param name="serverName"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string ExceptionContent(string serverName, ExceptionModel model)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("    using System;");
            sb.AppendLine($"   namespace {serverName}.Core.Exceptions");
            sb.AppendLine("    {");

            BuildDescription(model.Description, sb);

            sb.AppendLine($"        public class {model.Name}Exception : {serverName}BusinessException");
            sb.AppendLine("         {");
            if (model.HasParams.ToBooleanOrDefault())
            {
                BuildDescription(model.Description, sb);

                sb.AppendLine($@"           public {model.Name}Exception(params string[] parameters)
                                        :base({serverName}StatusCode.{model.Name},parameters)");
                sb.AppendLine(@"            { }");

                BuildDescription(model.Description, sb);

                sb.AppendLine($@"           public {model.Name}Exception(Exception excep,params string[] parameters)
                                         : base({serverName}StatusCode.{model.Name},excep,parameters)");


                sb.AppendLine(@"            { }");
            }
            else
            {
               

                BuildDescription(model.Description, sb);

                sb.AppendLine($@"           public {model.Name}Exception()
                                        :base({serverName}StatusCode.{model.Name})");
                sb.AppendLine(@"            { }");

                BuildDescription(model.Description, sb);

                sb.AppendLine($@"           public {model.Name}Exception(Exception excep)
                                         : base({serverName}StatusCode.{model.Name},excep)");


                sb.AppendLine(@"            { }");
            }

            sb.AppendLine("         }");
            sb.AppendLine("     }   ");
            return sb.ToString();
        }

        /// <summary>
        /// 业务异常主类
        /// </summary>
        /// <param name="serverName"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string BusissionExceptionContent(string serverName, ExceptionModel model)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(@"  using ServiceCore.Abstractions;");
            sb.AppendLine(@"  using System;");
            sb.AppendLine(@"  using System.Collections.Generic;");
            sb.AppendLine(@"  using System.Text; ");

            sb.AppendLine($"  namespace {serverName}.Core.Exceptions   ");
            sb.AppendLine("   {   ");

            BuildDescription(model.Description,sb);
            
            sb.AppendLine($"     public class {serverName}BusinessException : BusinessException");
            sb.AppendLine("      {");

            BuildDescription(model.Description, sb);
            sb.AppendLine($@"       public {serverName}BusinessException({serverName}StatusCode status)
                                    :base((int) status,status.Description())
                                    ");
            sb.AppendLine(@"        { }");

            BuildDescription(model.Description, sb);

            sb.AppendLine($@"       public {serverName}BusinessException({serverName}StatusCode status, params string[] parameters)
                                    :base((int)status, string.Format(status.Description(), parameters))
            ");
            sb.AppendLine(@"        { }");

            BuildDescription(model.Description, sb);

            sb.AppendLine($@"       public {serverName}BusinessException({serverName}StatusCode status, Exception innerException)
                                    :base((int)status,status.Description(),innerException)
                                     ");
            sb.AppendLine(@"        { }");


            BuildDescription(model.Description, sb);


            sb.AppendLine($@"       public {serverName}BusinessException({serverName}StatusCode status,Exception innerException, params string[] parameters)
                                    :base((int)status, string.Format(status.Description(), parameters),innerException)
                                    ");
            sb.AppendLine(@"        { }");
            sb.AppendLine("      }");
            sb.AppendLine("   }   ");
            return sb.ToString();

        }

        public static void BuildDescription(string description,StringBuilder sb)
        {
            sb.AppendLine("      ///<summary>");
            sb.AppendLine($"     /// {description}的异常");
            sb.AppendLine("      /// </summary>");
        }

        /// <summary>
        /// 异常枚举模版
        /// </summary>
        /// <param name="statuCodes"></param>
        /// <param name="serverName"></param>
        /// <returns></returns>
        public static string EnumExceptionStatuCode(IEnumerable<XmlStatuCode> statuCodes,string serverName)
        {
            var statuCode = statuCodes.SelectMany(p => p.Exceptions);


            StringBuilder sb = new StringBuilder();
            sb.AppendLine("    using System;");
            sb.AppendLine("    using System.ComponentModel;");
            
            sb.AppendLine($"   namespace {serverName}.Core");
            sb.AppendLine("    {");

            BuildDescription("异常枚举",sb);

            sb.AppendLine($"     public enum {serverName}StatusCode");
            sb.AppendLine("      {");

            


            foreach (var code in statuCode)
            {
                BuildDescription(code.Description, sb);
                sb.AppendLine($"       [Description(\"{ code.Message}\")]");
                sb.AppendLine($"       {code.Name} = {code.Value},");
            }

           

            sb.AppendLine("      }");
            sb.AppendLine("    }");

            return sb.ToString();
        }
    }
}
