// Copyright 2015 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.packages.util;

import static com.google.common.truth.Truth.assertWithMessage;

import com.google.devtools.build.docgen.DocCheckerUtils;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.exec.TestPolicy;
import com.google.devtools.build.lib.runtime.BlazeCommand;
import com.google.devtools.build.lib.runtime.BlazeCommandUtils;
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.BlazeRuntime;
import com.google.devtools.build.lib.runtime.BuiltinCommandModule;
import com.google.devtools.build.lib.runtime.ServerBuilder;
import com.google.devtools.build.lib.runtime.commands.RunCommand;
import com.google.devtools.common.options.Options;
import com.google.devtools.common.options.OptionsBase;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** Utility functions for validating correctness of Bazel documentation. */
public abstract class DocumentationTestUtil {

  private static final class DummyBuiltinCommandModule extends BuiltinCommandModule {
    DummyBuiltinCommandModule() {
      super(new RunCommand(TestPolicy.EMPTY_POLICY));
    }
  }

  private DocumentationTestUtil() {}

  private static final Pattern CODE_FLAG_PATTERN =
      Pattern.compile(
          "<code class\\s*=\\s*[\"']flag[\"']\\s*>--([a-z_\\[\\]]*)<\\/code>",
          Pattern.CASE_INSENSITIVE);

  /**
   * Validates that a user manual {@code documentationSource} contains only the flags actually
   * provided by a given set of modules.
   */
  public static void validateUserManual(
      List<Class<? extends BlazeModule>> modules,
      ConfiguredRuleClassProvider ruleClassProvider,
      String documentationSource,
      Set<String> extraValidOptions)
      throws Exception {
    // if there is a class missing, one can find it using
    //   find . -name "*.java" -exec grep -Hn "@Option(name = " {} \; | grep "xxx"
    // where 'xxx' is a flag name.
    List<BlazeModule> blazeModules = BlazeRuntime.createModules(modules);

    Set<String> validOptions = new HashSet<>();

    // collect all startup options
    for (Class<? extends OptionsBase> optionsClass :
        BlazeCommandUtils.getStartupOptions(blazeModules)) {
      validOptions.addAll(Options.getDefaults(optionsClass).asMap().keySet());
    }
    validOptions.addAll(extraValidOptions);

    // collect all command options
    ServerBuilder serverBuilder = new ServerBuilder();
    new DummyBuiltinCommandModule().serverInit(null, serverBuilder);
    for (BlazeModule module : blazeModules) {
      module.serverInit(null, serverBuilder);
    }
    List<BlazeCommand> blazeCommands = serverBuilder.getCommands();

    for (BlazeCommand command : blazeCommands) {
      for (Class<? extends OptionsBase> optionClass :
          BlazeCommandUtils.getOptions(command.getClass(), blazeModules, ruleClassProvider)) {
        validOptions.addAll(Options.getDefaults(optionClass).asMap().keySet());
      }
    }

    // check validity of option flags in manual
    Matcher anchorMatcher = CODE_FLAG_PATTERN.matcher(documentationSource);
    String flag;
    boolean found;

    while (anchorMatcher.find()) {
      flag = anchorMatcher.group(1);
      found = validOptions.contains(flag);
      if (!found && flag.startsWith("no")) {
        found = validOptions.contains(flag.substring(2));
      }
      if (!found && flag.startsWith("[no]")) {
        found = validOptions.contains(flag.substring(4));
      }

      assertWithMessage("flag '" + flag + "' is not a bazel option (anymore)").that(found).isTrue();
    }

    String unclosedTag = DocCheckerUtils.getFirstUnclosedTagAndPrintHelp(documentationSource);
    assertWithMessage("Unclosed tag found: " + unclosedTag).that(unclosedTag).isNull();
  }
}
