// Copyright 2020 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.profiler;

import com.google.auto.value.AutoValue;
import com.google.gson.stream.JsonReader;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Represents a single trace event in a JSON profile.
 *
 * <p>Format is documented in
 * https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 */
@AutoValue
public abstract class TraceEvent {
  public static TraceEvent create(
      @Nullable String category,
      String name,
      @Nullable Duration timestamp,
      @Nullable Duration duration,
      long threadId,
      @Nullable String primaryOutputPath) {
    return new AutoValue_TraceEvent(
        category, name, timestamp, duration, threadId, primaryOutputPath);
  }

  public static TraceEvent create(
      @Nullable String category,
      String name,
      @Nullable Duration timestamp,
      @Nullable Duration duration,
      long threadId) {
    return new AutoValue_TraceEvent(
        category, name, timestamp, duration, threadId, /* primaryOutputPath= */ null);
  }

  @Nullable
  public abstract String category();

  public abstract String name();

  @Nullable
  public abstract Duration timestamp();

  @Nullable
  public abstract Duration duration();

  public abstract long threadId();

  // Only applicable to action-related TraceEvents.
  @Nullable
  public abstract String primaryOutputPath();

  private static TraceEvent createFromJsonReader(JsonReader reader) throws IOException {
    String category = null;
    String name = null;
    Duration timestamp = null;
    Duration duration = null;
    long threadId = -1;
    String primaryOutputPath = null;

    reader.beginObject();
    while (reader.hasNext()) {
      switch (reader.nextName()) {
        case "cat":
          category = reader.nextString();
          break;
        case "name":
          name = reader.nextString();
          break;
        case "ts":
          // Duration has no microseconds :-/.
          timestamp = Duration.ofNanos(reader.nextLong() * 1000);
          break;
        case "dur":
          duration = Duration.ofNanos(reader.nextLong() * 1000);
          break;
        case "tid":
          threadId = reader.nextLong();
          break;
        case "out":
          primaryOutputPath = reader.nextString();
          break;
        default:
          reader.skipValue();
      }
    }
    reader.endObject();
    return TraceEvent.create(category, name, timestamp, duration, threadId, primaryOutputPath);
  }

  public static List<TraceEvent> parseTraceEvents(JsonReader reader) throws IOException {
    List<TraceEvent> traceEvents = new ArrayList<>();
    reader.beginArray();
    while (reader.hasNext()) {
      traceEvents.add(createFromJsonReader(reader));
    }
    reader.endArray();
    return traceEvents;
  }
}

@@ -1457,318 +1457,8 @@
  %7D%0A%0A
-  public static TraceEvent create(%0A      @Nullable String category,%0A      String name,%0A      @Nullable Duration timestamp,%0A      @Nullable Duration duration,%0A      long threadId) %7B%0A    return new AutoValue_TraceEvent(%0A        category, name, timestamp, duration, threadId, /* primaryOutputPath= */ null);%0A  %7D%0A%0A
   @N

Delete unused code.