// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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
//
//    http://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.devtools.build.lib.includescanning;

import com.google.devtools.build.lib.actions.LocalHostCapacity;
import com.google.devtools.common.options.Converters.IntegerConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParsingException;

/**
 * Command options specific to include scanning.
 */
public class IncludeScanningOptions extends OptionsBase {

  /**
   * Converter for a number of threads or {@code auto}, which automatically selects a value that
   * makes sense according to the local machine resources.
   */
  public static class ParallelismConverter extends IntegerConverter {
    @Override
    public Integer convert(String input) throws OptionsParsingException {
      if (input.equals("auto")) {
        return (int) Math.ceil(LocalHostCapacity.getLocalHostCapacity().getCpuUsage());
      } else {
        return super.convert(input);
      }
    }

    @Override
    public String getTypeDescription() {
      return "\"auto\" or " + super.getTypeDescription();
    }
  }

  @Option(
    name = "experimental_inmemory_dotincludes_files",
    documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
    effectTags = {
      OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION,
      OptionEffectTag.EXECUTION,
      OptionEffectTag.HOST_MACHINE_RESOURCE_OPTIMIZATIONS
    },
    defaultValue = "false",
    help =
        "If enabled, searching for '#include' lines in generated header files will not "
            + "touch local disk. This makes include scanning of C++ files less disk-intensive."
  )
  public boolean inMemoryIncludesFiles;

  @Option(
      name = "experimental_remote_include_extraction_size_threshold",
      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
      effectTags = {
          OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION,
          OptionEffectTag.EXECUTION,
          OptionEffectTag.HOST_MACHINE_RESOURCE_OPTIMIZATIONS
      },
      defaultValue = "1000000",
      help = "Run remotable C++ include extraction remotely if the file size in bytes exceeds this."
  )
  public int experimentalRemoteExtractionThreshold;

  @Option(
    name = "experimental_skyframe_include_scanning",
    documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
    effectTags = {
      OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION,
      OptionEffectTag.EXECUTION,
      OptionEffectTag.HOST_MACHINE_RESOURCE_OPTIMIZATIONS
    },
    defaultValue = "false",
    deprecationWarning = "No longer active: is a no-op",
    help = "Deprecated, has no effect."
  )
  public boolean skyframeIncludeScanning;

  @Option(
      name = "experimental_include_scanning_parallelism",
      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
      effectTags = {
          OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION,
          OptionEffectTag.EXECUTION,
          OptionEffectTag.HOST_MACHINE_RESOURCE_OPTIMIZATIONS
      },
      defaultValue = "80",
      converter = ParallelismConverter.class,
      help =
          "Configures the size of the thread pool used for include scanning. "
              + "0 means to disable parallelism and to just rely on the build graph parallelism "
              + "for concurrency. "
              + " \"auto\" means to use a reasonable value derived from the machine's hardware"
              + " profile (e.g. the number of processors)."
  )
  public int includeScanningParallelism;
}

@@ -759,41 +759,31 @@
 ols.
-common.options.Converters.Integer
+build.lib.util.Resource
 Conv
@@ -1237,143 +1237,102 @@
 for 
-a number of threads or %7B@code auto%7D, which automatically selects a value that%0A   * makes sense according to the local machine resources
+scanning parallelism threads: Takes %7B@value #FLAG_SYNTAX%7D 0 disables scanning%0A   * parallelism
 .%0A  
@@ -1386,23 +1386,24 @@
 extends 
-Integer
+Resource
 Converte
@@ -1414,125 +1414,119 @@
     
-@Override%0A    public Integer convert(String input) throws OptionsParsingException %7B%0A      if (input.equals(%22auto%22)) %7B
+public ParallelismConverter() throws OptionsParsingException %7B%0A      super(%0A          /* autoSupplier= */ () -%3E
 %0A   
@@ -1530,22 +1530,21 @@
         
-return
+     
  (int) M
@@ -1611,187 +1611,82 @@
 e())
-;
+,
 %0A      
-%7D else %7B%0A        return super.convert(input);%0A      %7D
+    /* minValue= */ 0,
 %0A    
-%7D%0A%0A
     
-@Override%0A    public String getTypeDescription() %7B%0A      return %22%5C%22auto%5C%22 or %22 + super.getTypeDescription(
+  /* maxValue= */ Integer.MAX_VALUE
 );%0A 
@@ -3433,34 +3433,32 @@
 ags = %7B%0A        
-  
 OptionEffectTag.
@@ -3487,34 +3487,32 @@
 RATION,%0A        
-  
 OptionEffectTag.
@@ -3514,34 +3514,32 @@
 tTag.EXECUTION,%0A
-  
         OptionEf
@@ -3753,16 +3753,22 @@
 canning.
+ Takes
  %22%0A     
@@ -3778,17 +3778,65 @@
       + 
-%22
+ResourceConverter.FLAG_SYNTAX%0A              + %22. 
 0 means 
@@ -4099,19 +4099,16 @@
 ssors).%22
-%0A  
 )%0A  publ

Add support for "HOST_CPUS" and "HOST_RAM" to --experimental_include_scanning_parallelism.