/*
 * Copyright 2016 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.idea.blaze.base.command;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.section.sections.BuildFlagsSection;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.intellij.openapi.project.Project;
import com.intellij.util.PlatformUtils;
import java.util.List;

/** The collection of all the Bazel flag strings we use. */
public final class BlazeFlags {

  // Build the maximum number of possible dependencies of the project and to show all the build
  // errors in single go.
  public static final String KEEP_GOING = "--keep_going";
  // Tells Blaze to open a debug port and wait for a connection while running tests
  // It expands to: --test_arg=--wrapper_script_flag=--debug --test_output=streamed
  //   --test_strategy=exclusive --test_timeout=9999 --nocache_test_results
  public static final String JAVA_TEST_DEBUG = "--java_debug";
  // Tells the Java wrapper stub to launch JVM in remote debugging mode, waiting for a connection
  public static final String JAVA_BINARY_DEBUG = "--debug";
  // Runs tests locally, in sequence (rather than parallel), and streams their results to stdout.
  public static final String TEST_OUTPUT_STREAMED = "--test_output=streamed";
  // Filters the unit tests that are run (used with regexp for Java/Robolectric tests).
  public static final String TEST_FILTER = "--test_filter";
  // Skips checking for output file modifications (reduced statting -> faster).
  public static final String NO_CHECK_OUTPUTS = "--noexperimental_check_output_files";
  // Ignores implicit dependencies (e.g. java_library rules depending implicitly on
  // "//transconsole/tools:aggregate_messages" in order to support translations).
  public static final String NO_IMPLICIT_DEPS = "--noimplicit_deps";
  // Ignores host dependencies.
  public static final String NO_HOST_DEPS = "--nohost_deps";
  // When used with mobile-install, deploys the an app incrementally.
  public static final String INCREMENTAL = "--incremental";
  // When used with mobile-install, deploys the an app incrementally
  // can be used for API 23 or higher, for which it is preferred to --incremental
  public static final String SPLIT_APKS = "--split_apks";
  // Re-run the test even if the results are cached.
  public static final String NO_CACHE_TEST_RESULTS = "--nocache_test_results";
  // Avoids node GC between ide_build_info and blaze build
  public static final String VERSION_WINDOW_FOR_DIRTY_NODE_GC =
      "--version_window_for_dirty_node_gc=-1";

  public static final String EXPERIMENTAL_SHOW_ARTIFACTS = "--experimental_show_artifacts";

  public static List<String> buildFlags(Project project, ProjectViewSet projectViewSet) {
    BuildSystem buildSystem = Blaze.getBuildSystem(project);
    List<String> flags = Lists.newArrayList();
    for (BuildFlagsProvider buildFlagsProvider : BuildFlagsProvider.EP_NAME.getExtensions()) {
      buildFlagsProvider.addBuildFlags(buildSystem, projectViewSet, flags);
    }
    flags.addAll(projectViewSet.listItems(BuildFlagsSection.KEY));
    return flags;
  }

  // Pass-through arg for sending adb options during mobile-install.
  public static final String ADB_ARG = "--adb_arg=";

  public static ImmutableList<String> adbSerialFlags(String serial) {
    return ImmutableList.of(ADB_ARG + "-s ", ADB_ARG + serial);
  }

  // Pass-through arg for sending test arguments.
  public static final String TEST_ARG = "--test_arg=";

  private static final String TOOL_TAG = "--tool_tag=ijwb:";

  // We add this to every single BlazeCommand instance. It's for tracking usage.
  public static String getToolTagFlag() {
    String platformPrefix = PlatformUtils.getPlatformPrefix();

    // IDEA Community Edition is "Idea", whereas IDEA Ultimate Edition is "idea".
    // That's dumb. Let's make them more useful.
    if (PlatformUtils.isIdeaCommunity()) {
      platformPrefix = "IDEA:community";
    } else if (PlatformUtils.isIdeaUltimate()) {
      platformPrefix = "IDEA:ultimate";
    }
    return TOOL_TAG + platformPrefix;
  }

  private BlazeFlags() {}
}
