/* Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.api.codegen.configgen;

import com.google.api.codegen.config.FieldModel;
import com.google.api.codegen.config.MethodModel;
import com.google.api.codegen.config.ProtoMethodModel;
import com.google.api.codegen.configgen.nodes.ConfigNode;
import com.google.api.codegen.configgen.nodes.FieldConfigNode;
import com.google.api.codegen.configgen.nodes.NullConfigNode;

/** PageStreamingTransformer implementation for proto Methods. */
public class ProtoPageStreamingTransformer implements PageStreamingTransformer {
  private static final PagingParameters PAGING_PARAMETERS = new ProtoPagingParameters();

  @Override
  public String getNameForPageToken() {
    return PAGING_PARAMETERS.getNameForPageToken();
  }

  @Override
  public String getNameForPageSize() {
    return PAGING_PARAMETERS.getNameForPageSize();
  }

  @Override
  public ConfigNode generateResponseValueNode(
      ConfigNode parentNode, MethodModel method, ConfigHelper helper) {
    if (!hasResponseTokenField(method)) {
      return new NullConfigNode();
    }

    String resourcesFieldName = getResourcesFieldName(method, helper);
    if (resourcesFieldName == null) {
      return new NullConfigNode();
    }

    ConfigNode tokenFieldNode =
        FieldConfigNode.createStringPair(
            NodeFinder.getNextLine(parentNode),
            "token_field",
            PAGING_PARAMETERS.getNameForNextPageToken());
    parentNode.setChild(tokenFieldNode);
    ConfigNode resourcesFieldNode =
        FieldConfigNode.createStringPair(
            NodeFinder.getNextLine(tokenFieldNode), "resources_field", resourcesFieldName);
    return tokenFieldNode.insertNext(resourcesFieldNode);
  }

  private boolean hasResponseTokenField(MethodModel method) {
    FieldModel tokenField = method.getOutputField(PAGING_PARAMETERS.getNameForNextPageToken());
    return tokenField != null;
  }

  private String getResourcesFieldName(MethodModel method, ConfigHelper helper) {
    String resourcesField = null;
    for (FieldModel field : method.getOutputFields()) {
      if (!field.isRepeated()) {
        continue;
      }

      if (resourcesField != null) {
        helper.error(
            ((ProtoMethodModel) method).getProtoMethod().getLocation(),
            "Page streaming resources field could not be heuristically determined for "
                + "method '%s'%n",
            method.getSimpleName());
        return null;
      }

      resourcesField = field.getSimpleName();
    }
    return resourcesField;
  }
}

@@ -2547,42 +2547,8 @@
 ) %7B%0A
-    String resourcesField = null;%0A
     
@@ -2595,24 +2595,66 @@
 Fields()) %7B%0A
+      // Return the first repeated field.%0A
       if (!f
@@ -2651,17 +2651,16 @@
     if (
-!
 field.is
@@ -2685,16 +2685,36 @@
     
-continue
+return field.getSimpleName()
 ;%0A  
@@ -2723,53 +2723,19 @@
   %7D%0A
-%0A  
     
-if (resourcesField != null) %7B%0A   
+%7D%0A%0A
     
- 
 help
@@ -2744,20 +2744,16 @@
 .error(%0A
-    
         
@@ -2820,20 +2820,16 @@
         
-   
- 
 %22Page st
@@ -2908,20 +2908,16 @@
         
-    
 + %22metho
@@ -2935,20 +2935,16 @@
         
-   
- 
 method.g
@@ -2960,20 +2960,16 @@
 ame());%0A
-    
     retu
@@ -2981,96 +2981,8 @@
 ll;%0A
-      %7D%0A%0A      resourcesField = field.getSimpleName();%0A    %7D%0A    return resourcesField;%0A
   %7D%0A

Improve page streaming heuristic (#2169)