csharp/188867052/Route.Generator/Shared/RouteGenerator.cs

RouteGenerator.cs
namespace Route.Generator
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using UnitTest;

    public clast RouteGenerator
    {
        private static CommondConfig config;

        public static string GenerateRoutes(IList infos)
        {
            StringBuilder sb = new StringBuilder();
            var group = infos.GroupBy(o => o.Namespace);
            sb.AppendLine($"using {typeof(object).Namespace};");
            sb.AppendLine($"using {typeof(Dictionary).Namespace};");
            sb.AppendLine($"using {typeof(Task).Namespace};");
            sb.AppendLine($"using {typeof(HttpClientAsync).Namespace};");

            sb.AppendLine();
            for (int i = 0; i < group.Count(); i++)
            {
                sb.Append(GenerateNamespace(group.ElementAt(i), i == (group.Count() - 1)));
            }

            return sb.ToString();
        }

        public async Task GenerateCodeAsync(CommondConfig config)
        {
            RouteGenerator.config = config;
            var routeInfos = new TestSite("Api").GetAllRouteInfo();
            return GenerateRoutes(routeInfos);
        }

        private static StringBuilder GenerateNamespace(IGrouping namespaceGroup, bool isLast)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"namespace {GetConvertedNamespace(namespaceGroup.Key)}");
            sb.AppendLine("{");

            var group = namespaceGroup.GroupBy(o => o.ControllerName);
            for (int i = 0; i < group.Count(); i++)
            {
                sb.Append(GenerateClast(group.ElementAt(i), i == (group.Count() - 1)));
            }

            sb.AppendLine("}");
            if (!isLast)
            {
                sb.AppendLine();
            }

            return sb;
        }

        private static StringBuilder GenerateClast(IGrouping group, bool isLast)
        {
            string clastFullName = $"{group.First().Namespace}.{group.First().ControllerName}Controller";
            string crefNamespace = GetCrefNamespace(clastFullName, GetConvertedNamespace(group.First().Namespace));
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"    /// ");
            sb.AppendLine($"    /// ");
            sb.AppendLine($"    /// ");
            sb.AppendLine($"    public clast {group.Key}Route");
            sb.AppendLine("    {");
            for (int i = 0; i < group.Count(); i++)
            {
                var item = group.ElementAt(i);
                var renamedAction = RenameOverloadedAction(group, i);
                sb.AppendLine("        /// ");
                sb.AppendLine($"        /// ");
                sb.AppendLine("        /// ");
                sb.AppendLine($"        public const string {renamedAction} = \"{item.Path}\";");

                if (config != null && config.GenerateMethod)
                {
                    sb.AppendLine($"        public static async Task {item.ActionName}Async({GeneraParameters(item.Parameters, true, false)})");
                    sb.AppendLine("        {");
                    sb.AppendLine($"            var routeInfo = new {nameof(RouteInfo)}");
                    sb.AppendLine("            {");
                    sb.AppendLine($"                {nameof(RouteInfo.HttpMethods)} = \"{item.HttpMethods}\",");
                    sb.AppendLine($"                {nameof(RouteInfo.Path)} = {renamedAction},");
                    sb.Append(GenerateParameters(item.Parameters));
                    sb.AppendLine("            };");
                    sb.AppendLine($"            return await {nameof(HttpClientAsync)}.{nameof(HttpClientAsync.Async)}(routeInfo{GeneraParameters(item.Parameters, false, true)});");
                    sb.AppendLine("        }");
                }

                if (i != group.Count() - 1)
                {
                    sb.AppendLine();
                }
            }

            sb.AppendLine("    }");
            if (!isLast)
            {
                sb.AppendLine();
            }

            return sb;
        }

        private static string GetConvertedNamespace(string name)
        {
            return name.Replace("Controllers", "Routes");
        }

        private static string RenameOverloadedAction(IGrouping group, int index)
        {
            var currensatem = group.ElementAt(index);
            var sameActionNameGroup = group.GroupBy(o => o.ActionName);
            foreach (var item in sameActionNameGroup)
            {
                if (item.Count() > 1)
                {
                    for (int i = 1; i < item.Count(); i++)
                    {
                        var element = item.ElementAt(i);
                        if (element == currensatem)
                        {
                            return element.ActionName + i;
                        }
                    }
                }
            }

            return currensatem.ActionName;
        }

        private static string GetCrefNamespace(string cref, string @namespace)
        {
            IList sameString = new List();
            var splitNamespace = @namespace.Split('.');
            var splitCref = cref.Split('.');
            int minLength = Math.Min(splitNamespace.Length, splitCref.Length);
            for (int i = 0; i < minLength; i++)
            {
                if (splitCref[i] == splitNamespace[i])
                {
                    sameString.Add(splitCref[i]);
                }
                else
                {
                    break;
                }
            }

            cref = cref.Substring(string.Join('.', sameString).Length + 1);
            return cref;
        }

        private static string GenerateParameters(IList parameters)
        {
            StringBuilder sb = new StringBuilder();
            if (parameters != null && parameters.Count > 0)
            {
                sb.AppendLine($"                {nameof(RouteInfo.Parameters)} = new List");
                sb.AppendLine("                {");
                foreach (var item in parameters)
                {
                    sb.AppendLine($"                    new {nameof(ParameterInfo)}() {{{nameof(item.Name)} = \"{item.Name}\", {nameof(item.Type)} = \"{item.Type}\"}},");
                }

                sb.AppendLine("                }");
            }

            return sb.ToString();
        }

        private static string GeneraParameters(IList parameters, bool hasType, bool hasPre)
        {
            StringBuilder sb = new StringBuilder();
            IList list = new List();
            if (parameters != null && parameters.Count > 0)
            {
                foreach (var item in parameters)
                {
                    if (hasType)
                    {
                        list.Add($"{item.Type} {item.Name}");
                    }
                    else
                    {
                        list.Add($"{item.Name}");
                    }
                }

                sb.Append((hasPre ? ", " : string.Empty) + string.Join(", ", list));
            }

            return sb.ToString();
        }
    }
}