public SwaggerRouteData Combine(SwaggerRouteData data)
 {
     var combined = new SwaggerRouteData(Path, PathItem.Combine(data.PathItem));
     foreach (var kvp in Types)
     {
         combined.Types.Add(kvp.Key, kvp.Value);
     }
     foreach (var kvp in data.Types)
     {
         combined.Types.Add(kvp.Key, kvp.Value);
     }
     return combined;
 }
        public SwaggerRouteData Combine(SwaggerRouteData data)
        {
            var combined = new SwaggerRouteData(Path, PathItem.Combine(data.PathItem));

            foreach (var kvp in Types)
            {
                combined.Types.Add(kvp.Key, kvp.Value);
            }
            foreach (var kvp in data.Types)
            {
                combined.Types.Add(kvp.Key, kvp.Value);
            }
            return(combined);
        }
        private SwaggerRouteData CreateSwaggerRouteData(INancyModule module, Route route, Dictionary<RouteId, MethodInfo> routeHandlers)
        {
            var data = new SwaggerRouteData(route.Description.Path, new PathItem());

            var routeId = RouteId.Create(module, route);
            var handler = routeHandlers.ContainsKey(routeId) ? routeHandlers[routeId] : null;
            var operation = new AnnotatedOperation(route.Description.Name, handler, _modelCatalog);

            var method = route.Description.Method.ToHttpMethod();
            switch (route.Description.Method.ToLowerInvariant())
            {
                case "get":
                    data.PathItem.Get = operation;
                    break;
                case "post":
                    data.PathItem.Post = operation;
                    break;
                case "patch":
                    data.PathItem.Patch = operation;
                    break;
                case "delete":
                    data.PathItem.Delete = operation;
                    break;
                case "put":
                    data.PathItem.Put = operation;
                    break;
                case "head":
                    data.PathItem.Head = operation;
                    break;
                case "options":
                    data.PathItem.Options = operation;
                    break;
            }

            if (operation.ResponseType != null)
            {
                data.Types.Add(method, operation.ResponseType);
            }

            return data;
        }
        private SwaggerRouteData CreateSwaggerRouteData(INancyModule module, Route route, Dictionary<RouteId, MethodInfo> routeHandlers)
        {
            var data = new SwaggerRouteData
            {
                ApiPath = route.Description.Path,
                ResourcePath = module.ModulePath.EnsureForwardSlash(),
                OperationMethod = route.Description.Method.ToHttpMethod(),
                OperationNickname = route.Description.Name
            };

            var routeId = RouteId.Create(module, route);
            var handler = routeHandlers.ContainsKey(routeId) ? routeHandlers[routeId] : null;
            if (handler == null)
            {
                data.OperationNotes = "[example]"; // TODO: Insert example how to annotate a route
                data.OperationSummary = "Warning: no annotated method found for this route";

                return data;
            }

            foreach (var attr in handler.GetCustomAttributes<RouteAttribute>())
            {
                data.OperationSummary = attr.Summary ?? data.OperationSummary;
                data.OperationNotes = attr.Notes ?? data.OperationNotes;
                data.OperationModel = attr.Response ?? data.OperationModel;
                data.OperationConsumes = attr.Consumes ?? data.OperationConsumes;
                data.OperationProduces = attr.Produces ?? data.OperationProduces;
            }

            data.OperationResponseMessages = handler.GetCustomAttributes<SwaggerResponseAttribute>()
                .Select(attr => {
                    var msg = new ResponseMessage
                    {
                        Code = (int)attr.Code,
                        Message = attr.Message                    
                    };
                    
                    if (attr.Model != null) 
                    {
                        msg.ResponseModel = Primitive.IsPrimitive(attr.Model) 
                                                ? Primitive.FromType(attr.Model).Type
                                                : SwaggerConfig.ModelIdConvention(attr.Model);
                    }

                    return msg;
                })
                .ToList();


            data.OperationParameters = handler.GetParameters()
                .Select(CreateSwaggerParameterData)
                .ToList();

            return data;
        }
        private SwaggerRouteData CreateSwaggerRouteData(INancyModule module, Route route, Dictionary<RouteId, MethodInfo> routeHandlers)
        {
            var operation = new Operation()
            {
                OperationId = route.Description.Name
            };


            var data = new SwaggerRouteData(route.Description.Path, new PathItem());

            var method = route.Description.Method.ToHttpMethod();
            switch (route.Description.Method.ToLowerInvariant())
            {
                case "get":
                    data.PathItem.Get = operation;
                    break;
                case "post":
                    data.PathItem.Post = operation;
                    break;
                case "patch":
                    data.PathItem.Patch = operation;
                    break;
                case "delete":
                    data.PathItem.Delete = operation;
                    break;
                case "put":
                    data.PathItem.Put = operation;
                    break;
                case "head":
                    data.PathItem.Head = operation;
                    break;
                case "options":
                    data.PathItem.Options = operation;
                    break;
            }

            var routeId = RouteId.Create(module, route);
            var handler = routeHandlers.ContainsKey(routeId) ? routeHandlers[routeId] : null;
            if (handler == null)
            {
                operation.Description = "[example]"; // TODO: Insert example how to annotate a route
                operation.Summary = "Warning: no annotated method found for this route";

                return data;
            }

            Type model = null;
            foreach (var attr in handler.GetCustomAttributes<RouteAttribute>())
            {
                operation.Summary = attr.Summary ?? operation.Summary;
                operation.Description = attr.Notes ?? operation.Description;
                model = attr.Response ?? model;
                operation.Consumes = attr.Consumes ?? operation.Consumes;
                operation.Consumes = attr.Produces ?? operation.Produces;
            }

            if (model != null)
            {
                data.Types.Add(method, model);
            }

            operation.Responses = handler.GetCustomAttributes<SwaggerResponseAttribute>()
                .Select(attr =>
                {
                    var msg = new global::Swagger.ObjectModel.Response()
                    {
                        Description = attr.Message
                    };

                    //if (attr.Model != null)
                    //{
                    //    msg.ResponseModel = Primitive.IsPrimitive(attr.Model)
                    //                            ? Primitive.FromType(attr.Model).Type
                    //                            : SwaggerConfig.ModelIdConvention(attr.Model);
                    //}

                    return Tuple.Create((int)attr.Code, msg);
                })
                .ToDictionary(x => x.Item1.ToString(), x => x.Item2);


            operation.Parameters = handler.GetParameters()
                .Select(CreateSwaggerParameterData)
                .ToList();

            return data;
        }