// 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.devtools.build.lib.buildeventstream;

import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.ActionCompletedId;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.ConfigurationId;
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.protobuf.TextFormat;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

/**
 * Class of identifiers for publically posted events.
 *
 * <p>Since event identifiers need to be created before the actual event, the event IDs are highly
 * structured so that equal identifiers can easily be generated. The main way of pregenerating event
 * identifiers that do not accidentally coincide is by providing a target or a target pattern;
 * therefore, those (if provided) are made specially visible.
 */
@AutoCodec
@Immutable
public final class BuildEventId implements Serializable {
  private final BuildEventStreamProtos.BuildEventId protoid;

  @AutoCodec.VisibleForSerialization
  BuildEventId(BuildEventStreamProtos.BuildEventId protoid) {
    this.protoid = protoid;
  }

  @Override
  public int hashCode() {
    return Objects.hash(protoid);
  }

  @Override
  public boolean equals(Object other) {
    if (other == null || !other.getClass().equals(getClass())) {
      return false;
    }
    BuildEventId that = (BuildEventId) other;
    return Objects.equals(this.protoid, that.protoid);
  }

  @Override
  public String toString() {
    return "BuildEventId {" + TextFormat.printToString(protoid) + "}";
  }

  public BuildEventStreamProtos.BuildEventId asStreamProto() {
    return protoid;
  }

  public static BuildEventId unknownBuildEventId(String details) {
    BuildEventStreamProtos.BuildEventId.UnknownBuildEventId id =
        BuildEventStreamProtos.BuildEventId.UnknownBuildEventId.newBuilder()
            .setDetails(details)
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setUnknown(id).build());
  }

  public static BuildEventId progressId(int count) {
    BuildEventStreamProtos.BuildEventId.ProgressId id =
        BuildEventStreamProtos.BuildEventId.ProgressId.newBuilder().setOpaqueCount(count).build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setProgress(id).build());
  }

  public static BuildEventId buildStartedId() {
    BuildEventStreamProtos.BuildEventId.BuildStartedId startedId =
        BuildEventStreamProtos.BuildEventId.BuildStartedId.getDefaultInstance();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setStarted(startedId).build());
  }

  public static BuildEventId unstructuredCommandlineId() {
    BuildEventStreamProtos.BuildEventId.UnstructuredCommandLineId commandLineId =
        BuildEventStreamProtos.BuildEventId.UnstructuredCommandLineId.getDefaultInstance();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder()
            .setUnstructuredCommandLine(commandLineId)
            .build());
  }

  public static BuildEventId structuredCommandlineId(String commandLineLabel) {
    BuildEventStreamProtos.BuildEventId.StructuredCommandLineId commandLineId =
        BuildEventStreamProtos.BuildEventId.StructuredCommandLineId.newBuilder()
            .setCommandLineLabel(commandLineLabel)
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder()
            .setStructuredCommandLine(commandLineId)
            .build());
  }

  public static BuildEventId optionsParsedId() {
    BuildEventStreamProtos.BuildEventId.OptionsParsedId optionsParsedId =
        BuildEventStreamProtos.BuildEventId.OptionsParsedId.getDefaultInstance();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setOptionsParsed(optionsParsedId).build());
  }

  public static BuildEventId workspaceStatusId() {
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder()
            .setWorkspaceStatus(
                BuildEventStreamProtos.BuildEventId.WorkspaceStatusId.getDefaultInstance())
            .build());
  }

  public static BuildEventId buildMetadataId() {
    BuildEventStreamProtos.BuildEventId.BuildMetadataId buildMetadataId =
        BuildEventStreamProtos.BuildEventId.BuildMetadataId.getDefaultInstance();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setBuildMetadata(buildMetadataId).build());
  }

  public static BuildEventId workspaceConfigId() {
    BuildEventStreamProtos.BuildEventId.WorkspaceConfigId workspaceConfigId =
        BuildEventStreamProtos.BuildEventId.WorkspaceConfigId.getDefaultInstance();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setWorkspace(workspaceConfigId).build());
  }

  public static BuildEventId fetchId(String url) {
    BuildEventStreamProtos.BuildEventId.FetchId fetchId =
        BuildEventStreamProtos.BuildEventId.FetchId.newBuilder().setUrl(url).build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setFetch(fetchId).build());
  }

  public static BuildEventId configurationId(String id) {
    BuildEventStreamProtos.BuildEventId.ConfigurationId configurationId =
        BuildEventStreamProtos.BuildEventId.ConfigurationId.newBuilder().setId(id).build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setConfiguration(configurationId).build());
  }

  public static BuildEventId nullConfigurationId() {
    return configurationId("none");
  }

  private static BuildEventId targetPatternExpanded(List<String> targetPattern, boolean skipped) {
    BuildEventStreamProtos.BuildEventId.PatternExpandedId patternId =
        BuildEventStreamProtos.BuildEventId.PatternExpandedId.newBuilder()
            .addAllPattern(targetPattern)
            .build();
    BuildEventStreamProtos.BuildEventId.Builder builder =
        BuildEventStreamProtos.BuildEventId.newBuilder();
    if (skipped) {
      builder.setPatternSkipped(patternId);
    } else {
      builder.setPattern(patternId);
    }
    return new BuildEventId(builder.build());
  }

  public static BuildEventId targetPatternExpanded(List<String> targetPattern) {
    return targetPatternExpanded(targetPattern, false);
  }

  public static BuildEventId targetPatternSkipped(List<String> targetPattern) {
    return targetPatternExpanded(targetPattern, true);
  }

  public static BuildEventId targetConfigured(Label label) {
    BuildEventStreamProtos.BuildEventId.TargetConfiguredId configuredId =
        BuildEventStreamProtos.BuildEventId.TargetConfiguredId.newBuilder()
            .setLabel(label.toString())
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setTargetConfigured(configuredId).build());
  }

  public static BuildEventId aspectConfigured(Label label, String aspect) {
    BuildEventStreamProtos.BuildEventId.TargetConfiguredId configuredId =
        BuildEventStreamProtos.BuildEventId.TargetConfiguredId.newBuilder()
            .setLabel(label.toString())
            .setAspect(aspect)
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setTargetConfigured(configuredId).build());
  }

  public static BuildEventId targetCompleted(Label target, BuildEventId configuration) {
    BuildEventStreamProtos.BuildEventId.ConfigurationId configId =
        configuration.protoid.getConfiguration();
    BuildEventStreamProtos.BuildEventId.TargetCompletedId targetId =
        BuildEventStreamProtos.BuildEventId.TargetCompletedId.newBuilder()
            .setLabel(target.toString())
            .setConfiguration(configId)
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setTargetCompleted(targetId).build());
  }

  public static BuildEventId configuredLabelId(Label label, BuildEventId configuration) {
    BuildEventStreamProtos.BuildEventId.ConfigurationId configId =
        configuration.protoid.getConfiguration();
    BuildEventStreamProtos.BuildEventId.ConfiguredLabelId labelId =
        BuildEventStreamProtos.BuildEventId.ConfiguredLabelId.newBuilder()
            .setLabel(label.toString())
            .setConfiguration(configId)
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setConfiguredLabel(labelId).build());
  }

  public static BuildEventId unconfiguredLabelId(Label label) {
    BuildEventStreamProtos.BuildEventId.UnconfiguredLabelId labelId =
        BuildEventStreamProtos.BuildEventId.UnconfiguredLabelId.newBuilder()
            .setLabel(label.toString())
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setUnconfiguredLabel(labelId).build());
  }

  public static BuildEventId aspectCompleted(
      Label target, BuildEventId configuration, String aspect) {
    BuildEventStreamProtos.BuildEventId.ConfigurationId configId =
        configuration.protoid.getConfiguration();
    BuildEventStreamProtos.BuildEventId.TargetCompletedId targetId =
        BuildEventStreamProtos.BuildEventId.TargetCompletedId.newBuilder()
            .setLabel(target.toString())
            .setConfiguration(configId)
            .setAspect(aspect)
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setTargetCompleted(targetId).build());
  }

  public static BuildEventId fromCause(Cause cause) {
    return new BuildEventId(cause.getIdProto());
  }

  public static BuildEventId actionCompleted(PathFragment path) {
    return actionCompleted(path, null, null);
  }

  public static BuildEventId actionCompleted(
      PathFragment path, @Nullable Label label, @Nullable String configurationChecksum) {
    ActionCompletedId.Builder actionId =
        ActionCompletedId.newBuilder().setPrimaryOutput(path.toString());
    if (label != null) {
      actionId.setLabel(label.toString());
    }
    if (configurationChecksum != null) {
      actionId.setConfiguration(ConfigurationId.newBuilder().setId(configurationChecksum));
    }
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setActionCompleted(actionId).build());
  }

  public static BuildEventId fromArtifactGroupName(String name) {
    BuildEventStreamProtos.BuildEventId.NamedSetOfFilesId namedSetId =
        BuildEventStreamProtos.BuildEventId.NamedSetOfFilesId.newBuilder().setId(name).build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setNamedSet(namedSetId).build());
  }

  public static BuildEventId testResult(
      Label target, Integer run, Integer shard, Integer attempt, BuildEventId configuration) {
    BuildEventStreamProtos.BuildEventId.ConfigurationId configId =
        configuration.protoid.getConfiguration();
    BuildEventStreamProtos.BuildEventId.TestResultId resultId =
        BuildEventStreamProtos.BuildEventId.TestResultId.newBuilder()
            .setLabel(target.toString())
            .setConfiguration(configId)
            .setRun(run + 1)
            .setShard(shard + 1)
            .setAttempt(attempt)
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setTestResult(resultId).build());
  }

  public static BuildEventId testResult(
      Label target, Integer run, Integer shard, BuildEventId configuration) {
    return testResult(target, run, shard, 1, configuration);
  }

  public static BuildEventId testSummary(Label target, BuildEventId configuration) {
    BuildEventStreamProtos.BuildEventId.ConfigurationId configId =
        configuration.protoid.getConfiguration();
    BuildEventStreamProtos.BuildEventId.TestSummaryId summaryId =
        BuildEventStreamProtos.BuildEventId.TestSummaryId.newBuilder()
            .setLabel(target.toString())
            .setConfiguration(configId)
            .build();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setTestSummary(summaryId).build());
  }

  public static BuildEventId buildFinished() {
    BuildEventStreamProtos.BuildEventId.BuildFinishedId finishedId =
        BuildEventStreamProtos.BuildEventId.BuildFinishedId.getDefaultInstance();
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder().setBuildFinished(finishedId).build());
  }

  public static BuildEventId buildToolLogs() {
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder()
            .setBuildToolLogs(
                BuildEventStreamProtos.BuildEventId.BuildToolLogsId.getDefaultInstance())
            .build());
  }

  public static BuildEventId buildMetrics() {
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder()
            .setBuildMetrics(
                BuildEventStreamProtos.BuildEventId.BuildMetricsId.getDefaultInstance())
            .build());
  }

  public static BuildEventId convenienceSymlinksIdentifiedId() {
    return new BuildEventId(
        BuildEventStreamProtos.BuildEventId.newBuilder()
            .setConvenienceSymlinksIdentified(
                BuildEventStreamProtos.BuildEventId.ConvenienceSymlinksIdentifiedId
                    .getDefaultInstance())
            .build());
  }
}
