private string GenerateEnumerableMethodForBatchApiEndpoint()

in src/JetBrains.Space.Generator/CodeGeneration/CSharp/Generators/CSharpApiModelResourceGenerator.cs [383:498]


    private string GenerateEnumerableMethodForBatchApiEndpoint(ApiEndpoint apiEndpoint, string baseEndpointPath)
    {
        var requestBodyObject = apiEndpoint.RequestBody as ApiFieldType.Object;

        var indent = new Indent();
        var builder = new CSharpBuilder();

        var endpointPath = (baseEndpointPath + "/" + apiEndpoint.Path.Segments.ToPath()).TrimEnd('/');

        var methodNameForEndpoint = apiEndpoint.ToCSharpMethodName();

        var batchDataType = ((ApiFieldType.Object)apiEndpoint.ResponseBody!).GetBatchDataType()!;

        var hasSkipParameter = apiEndpoint.Parameters.Any(it => it.Field.Name == "$skip") ||
                               requestBodyObject?.Fields.Any(it => it.Name == "skip") == true;
        var hasBatchInfoParameter = requestBodyObject?.Fields.Any(it => it.Name == "batchInfo") == true;

        if (apiEndpoint.ResponseBody != null && (hasSkipParameter || hasBatchInfoParameter))
        {
            var methodParametersBuilder = new MethodParametersBuilder(_codeGenerationContext)
                .WithParametersForApiParameters(apiEndpoint.Parameters);

            if (apiEndpoint.RequestBody != null)
            {
                if (requestBodyObject != null && FeatureFlags.DoNotExposeRequestObjects)
                {
                    methodParametersBuilder = methodParametersBuilder
                        .WithParametersForApiFields(requestBodyObject.Fields);
                }
                else
                {
                    methodParametersBuilder = methodParametersBuilder
                        .WithParameter(
                            apiEndpoint.ToCSharpRequestBodyClassName(endpointPath)!,
                            "data");
                }
            }
        
            var partialType = "Partial<" + batchDataType.GetBatchElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">";
            var funcType = $"Func<{partialType}, {partialType}>?";
            methodParametersBuilder = methodParametersBuilder
                .WithParameter(
                    funcType,
                    "partial",
                    CSharpExpression.NullLiteral);
                
            methodParametersBuilder = methodParametersBuilder
                .WithParameter(CSharpType.CancellationToken.Value,
                    "cancellationToken",
                    CSharpExpression.DefaultLiteral);

            builder.Append(
                indent.Wrap(GenerateMethodDocumentationForEndpoint(apiEndpoint, methodParametersBuilder)));
            builder.Append($"{indent}public IAsyncEnumerable<");
            builder.Append(batchDataType.ElementType.ToCSharpType(_codeGenerationContext));
            builder.Append(">");
            builder.Append($" {methodNameForEndpoint}AsyncEnumerable(");
            builder.Append(methodParametersBuilder.BuildMethodParametersList());
            builder.AppendLine(")");
                
            indent.Increment();

            if (hasSkipParameter)
            {
                // Batch enumerator v1 - Pass a "skip" parameter
                builder.Append($"{indent}=> BatchEnumerator.AllItems((batchSkip, batchCancellationToken) => ");

                builder.Append($"{methodNameForEndpoint}Async(");

                var partialTypeForBatch = "Partial<Batch<" + batchDataType.GetBatchElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">>";
                builder.Append(
                    methodParametersBuilder
                        .WithDefaultValueForAllParameters(null)
                        .WithDefaultValueForParameter("skip", "batchSkip")
                        .WithDefaultValueForParameter("partial", $"builder => {partialTypeForBatch}.Default().WithNext().WithTotalCount().WithData(partial != null ? partial : _ => {partialType}.Default())")
                        .WithDefaultValueForParameter(CSharpType.CancellationToken.Value, "batchCancellationToken")
                        .BuildMethodCallParameters());

                builder.Append("), skip, cancellationToken);");
            }
            else if (hasBatchInfoParameter)
            {
                // Batch enumerator v2 - Pass a "batchInfo" parameter
                builder.Append($"{indent}=> BatchEnumerator.AllItems((batchSkip, batchCancellationToken) => ");

                builder.Append($"{methodNameForEndpoint}Async(");

                var partialTypeForBatch = "Partial<Batch<" + batchDataType.GetBatchElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">>";
                builder.Append(
                    methodParametersBuilder
                        .WithDefaultValueForAllParameters(null)
                        .WithDefaultValueForParameter("batchInfo", "new BatchInfo(batchSize: batchInfo?.BatchSize ?? 100, offset: batchInfo?.Offset)")
                        .WithDefaultValueForParameter("partial", $"builder => {partialTypeForBatch}.Default().WithNext().WithTotalCount().WithData(partial != null ? partial : _ => {partialType}.Default())")
                        .WithDefaultValueForParameter(CSharpType.CancellationToken.Value, "batchCancellationToken")
                        .BuildMethodCallParameters());

                builder.Append("), batchInfo?.Offset, cancellationToken);");
            }
            else
            {
                builder.Append($"{indent}=> throw new Exception(\"No 'skip' or 'batchInfo' parameter exists for this method.\");");
            }

            indent.Decrement();
        }
        else if (!hasSkipParameter && !hasBatchInfoParameter)
        {
            builder.AppendLine($"{indent}#warning UNSUPPORTED CASE - NO SKIP OR BATCHINFO PARAMETER - " + apiEndpoint.ToCSharpMethodName() + " - " + apiEndpoint.Method.ToHttpMethod() + " " + endpointPath);
        }
        else
        {
            builder.AppendLine($"{indent}#warning UNSUPPORTED CASE - " + apiEndpoint.ToCSharpMethodName() + " - " + apiEndpoint.Method.ToHttpMethod() + " " + endpointPath);
        }

        return builder.ToString();
    }