// 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.query2.cquery;

import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider;
import com.google.devtools.build.lib.analysis.config.CoreOptions.IncludeConfigFragmentsEnum;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.TargetAccessor;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.build.lib.util.ClassName;
import java.io.OutputStream;

/** Default Output callback for cquery. Prints a label and configuration pair per result. */
public class LabelAndConfigurationOutputFormatterCallback extends CqueryThreadsafeCallback {
  private final boolean showKind;
  private final RepositoryMapping mainRepoMapping;

  LabelAndConfigurationOutputFormatterCallback(
      ExtendedEventHandler eventHandler,
      CqueryOptions options,
      OutputStream out,
      SkyframeExecutor skyframeExecutor,
      TargetAccessor<KeyedConfiguredTarget> accessor,
      boolean showKind,
      RepositoryMapping mainRepoMapping) {
    super(eventHandler, options, out, skyframeExecutor, accessor, /*uniquifyResults=*/ false);
    this.showKind = showKind;
    this.mainRepoMapping = mainRepoMapping;
  }

  @Override
  public String getName() {
    return this.showKind ? "label_kind" : "label";
  }

  @Override
  public void processOutput(Iterable<KeyedConfiguredTarget> partialResult) {
    for (KeyedConfiguredTarget keyedConfiguredTarget : partialResult) {
      StringBuilder output = new StringBuilder();
      if (showKind) {
        Target actualTarget = accessor.getTarget(keyedConfiguredTarget);
        output = output.append(actualTarget.getTargetKind()).append(" ");
      }
      output =
          output
              .append(keyedConfiguredTarget.getLabel().getDisplayForm(mainRepoMapping))
              .append(" (")
              .append(shortId(getConfiguration(keyedConfiguredTarget.getConfigurationKey())))
              .append(")");

      if (options.showRequiredConfigFragments != IncludeConfigFragmentsEnum.OFF) {
        output.append(' ').append(requiredFragmentStrings(keyedConfiguredTarget));
      }

      addResult(output.toString());
    }
  }

  private static ImmutableSortedSet<String> requiredFragmentStrings(
      KeyedConfiguredTarget keyedConfiguredTarget) {
    RequiredConfigFragmentsProvider requiredFragments =
        keyedConfiguredTarget
            .getConfiguredTarget()
            .getProvider(RequiredConfigFragmentsProvider.class);
    if (requiredFragments == null) {
      return ImmutableSortedSet.of();
    }

    return ImmutableSortedSet.<String>naturalOrder()
        .addAll(
            Iterables.transform(
                requiredFragments.getOptionsClasses(), ClassName::getSimpleNameWithOuter))
        .addAll(
            Iterables.transform(
                requiredFragments.getFragmentClasses(), ClassName::getSimpleNameWithOuter))
        .addAll(Iterables.transform(requiredFragments.getDefines(), define -> "--define:" + define))
        .addAll(Iterables.transform(requiredFragments.getStarlarkOptions(), Label::toString))
        .build();
  }
}
