private void AddAPIRequest(CoderStringBuilder output, Operation operation)
        {
            if (operation == null)
            {
                return;
            }

            if (operation.Parameters != null)
            {
                AddParameterInterface(output, $"{operation.OperationId}Request", operation.Parameters);
            }
        }
        private void AddParameterInterface(CoderStringBuilder output, string sourceName, Parameter[] parameters)
        {
            var name = CleanClassName(sourceName, false);

            if (existingInterfaces.Contains(name))
            {
                return;
            }

            existingInterfaces.Add(name);

            output.AppendLine($"export interface I{name} {{");
            output.Indent();
            foreach (var parameter in parameters)
            {
                var propertyName = parameter.Name;
                if (!parameter.Required)
                {
                    propertyName += "?";
                }

                var propertyType  = "any";
                var bodyParameter = parameter as BodyParameter;
                if (bodyParameter != null)
                {
                    propertyType = SchemaTypeCleaner(bodyParameter.Schema);
                }

                var otherParameter = parameter as OtherParameter;
                if (otherParameter != null)
                {
                    var arrayParameter = parameter as OtherArrayParameter;
                    if (arrayParameter != null)
                    {
                        propertyType = $"Array<{CleanClassName(arrayParameter.Items[0].Type)}>";
                    }
                    else
                    {
                        propertyType = CleanClassName(otherParameter.Type);
                    }
                }

                output.AppendLine($"{propertyName}: {propertyType};");
            }

            output.Outdent();
            output.AppendLine("}");
            output.AppendLine();
        }
        private void Process(CoderStringBuilder output, Specification specification)
        {
            output.AppendLine($"export module {CleanClassName(specification.Info.Title, false)} {{");
            output.Indent();
            foreach (var defination in specification.Definations)
            {
                AddTypes(output, defination.Name, defination.Properties);
            }

            foreach (var path in specification.Paths)
            {
                AddAPIRequest(output, path.Delete);
                AddAPIRequest(output, path.Get);
                AddAPIRequest(output, path.Head);
                AddAPIRequest(output, path.Options);
                AddAPIRequest(output, path.Patch);
                AddAPIRequest(output, path.Post);
                AddAPIRequest(output, path.Put);
            }

            output.AppendLine("export interface API {");
            output.Indent();
            output.AppendLine("setToken(value: string, headerOrQueryName: string, isQuery: boolean): void;");

            foreach (var path in specification.Paths)
            {
                AddAPICall(output, path, HTTPAction.Delete);
                AddAPICall(output, path, HTTPAction.Get);
                AddAPICall(output, path, HTTPAction.Head);
                AddAPICall(output, path, HTTPAction.Options);
                AddAPICall(output, path, HTTPAction.Patch);
                AddAPICall(output, path, HTTPAction.Post);
                AddAPICall(output, path, HTTPAction.Put);
            }

            output.Outdent();
            output.AppendLine("}");

            output.Outdent();
            output.AppendLine("}");
        }
        private void OutputBasicType(CoderStringBuilder output, bool typeIsClass, string name, Property[] properties, bool close = false, List <EnumInfo> enums = null)
        {
            var type       = "interface";
            var prefix     = "I";
            var implements = "";

            if (typeIsClass)
            {
                prefix     = "";
                type       = "class";
                implements = $" implements I{name}";
            }
            output.AppendLine($"export {type} {prefix}{name}{implements} {{");
            output.Indent();
            if (properties != null)
            {
                foreach (var property in properties)
                {
                    var propertyName = property.Name;
                    var propertyType = PropertyTypeCleaner(property);
                    if (property.Enum != null)
                    {
                        propertyType = "string";
                        enums?.Add(new EnumInfo
                        {
                            EnumPropertyName = propertyName,
                            EnumValues       = property.Enum,
                            EnumClassName    = name + propertyName
                        });
                    }

                    output.AppendLine($"{propertyName}: {propertyType};");
                }
            }

            if (close)
            {
                OutputBasicTypeClose(output);
            }
        }
        public void Run(Configuration swaggerConfig, Specification[] specifications)
        {
            existingInterfaces.Add("any");
            var output = new CoderStringBuilder();

            output.AppendLine($"//{Messages.VersionIdentifierPrefix}:{Configuration.nSwaggerVersion}");
            output.AppendLine($"// {Messages.Notice}");
            output.AppendLine($"// {Messages.LastGenerated} {DateTime.UtcNow:o}");
            output.AppendLine($"namespace {swaggerConfig.Namespace} {{");
            output.Indent();
            foreach (var specification in specifications.Where(_ => !_.Error))
            {
                Process(output, specification);
            }

            output.Outdent();
            output.AppendLine("}");

            if (!swaggerConfig.DoNotWriteTargetFile)
            {
                File.WriteAllText(swaggerConfig.Target, output.ToString());
            }
        }
        private void AddAPICall(CoderStringBuilder output, PathItem path, HTTPAction action)
        {
            var operation = default(Operation);

            switch (action)
            {
            case HTTPAction.Put:
            {
                operation = path.Put;
                break;
            }

            case HTTPAction.Get:
            {
                operation = path.Get;
                break;
            }

            case HTTPAction.Post:
            {
                operation = path.Post;
                break;
            }

            case HTTPAction.Delete:
            {
                operation = path.Delete;
                break;
            }

            case HTTPAction.Head:
            {
                operation = path.Head;
                break;
            }

            case HTTPAction.Options:
            {
                operation = path.Options;
                break;
            }

            case HTTPAction.Patch:
            {
                operation = path.Patch;
                break;
            }
            }
            if (operation == null)
            {
                return;
            }

            var parameters = "";

            if (operation.Parameters != null)
            {
                var optional = "";
                if (operation.Parameters.All(_ => !_.Required))
                {
                    optional = "?";
                }

                parameters = $"parameters{optional}: {CleanClassName($"{operation.OperationId}Request")}";
            }

            var methodName = "";

            if (operation.OperationId != null)
            {
                methodName = CleanClassName(operation.OperationId, false);
            }
            else
            {
                methodName = CleanClassName(GetPathToMethodName(action.ToString(), path.Path), false);
            }

            var operationContent = new StringBuilder($"{methodName}({parameters}): ");
            var success          = operation.Responses.FirstOrDefault(_ => _.HttpStatusCode >= 200 && _.HttpStatusCode <= 299);

            if (success == null || success.Schema == null)
            {
                operationContent.Append("PromiseLike<void>;");
            }
            else
            {
                operationContent.Append($"PromiseLike<{SchemaTypeCleaner(success.Schema)}>;");
            }

            output.AppendLine(operationContent.ToString());
        }
 private void OutputBasicTypeClose(CoderStringBuilder output)
 {
     output.Outdent();
     output.AppendLine("}");
     output.AppendLine();
 }
        private void AddTypes(CoderStringBuilder output, string sourceName, Property[] properties)
        {
            var enums = new List <EnumInfo>();
            var name  = CleanClassName(sourceName, false);

            if (existingInterfaces.Contains(name))
            {
                return;
            }

            existingInterfaces.Add(name);

            OutputBasicType(output, false, name, properties, true, enums);

            var enumProperties = (properties?.Any(_ => _.Enum != null));

            if (enumProperties.HasValue && enumProperties.Value)
            {
                OutputBasicType(output, true, name, properties);

                output.AppendLine();
                output.AppendLine("constructor(source?: any) {");
                output.Indent();
                output.AppendLine("if (source !== undefined) {");
                output.Indent();
                output.AppendLine("Object.assign(this, source);");
                output.Outdent();
                output.AppendLine("}");
                output.Outdent();
                output.AppendLine("}");

                foreach (var property in properties.Where(_ => _.Enum != null))
                {
                    var propertyName = property.Name;
                    var enumName     = name + propertyName;
                    output.AppendLine();
                    output.AppendLine($"get {propertyName}AsEnum(): {enumName} {{");
                    output.Indent();
                    output.AppendLine($"return {enumName}[this.{propertyName}];");
                    output.Outdent();
                    output.AppendLine("}");

                    output.AppendLine();
                    output.AppendLine($"set {propertyName}AsEnum(value:{enumName}) {{");
                    output.Indent();
                    output.AppendLine($"this.{propertyName} = {enumName}[value];");
                    output.Outdent();
                    output.AppendLine("}");
                }

                OutputBasicTypeClose(output);
            }

            foreach (var @enum in enums)
            {
                output.AppendLine($"export enum {@enum.EnumClassName} {{");
                output.Indent();
                var addComma = false;
                foreach (var enumValue in @enum.EnumValues)
                {
                    if (!addComma)
                    {
                        addComma = true;
                    }
                    else
                    {
                        output.AppendLine(",", true);
                    }

                    output.Append(enumValue);
                }
                output.AppendLine();
                output.Outdent();
                output.AppendLine("}");
                output.AppendLine();
            }
        }