// Copyright 2014 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.events;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.util.io.FileOutErr;
import com.google.devtools.build.lib.util.io.FileOutErr.OutputReference;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Objects;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

/**
 * An event is a situation encountered by the build system that's worth
 * reporting: A 3-tuple of ({@link EventKind}, {@link Location}, message).
 */
@Immutable
public final class Event implements Serializable {
  private final EventKind kind;
  private final Location location;
  private final String message;
  @Nullable private final FileOutErr outErr;

  /**
   * An alternative representation for message.
   *
   * <p>Exactly one of message or messageBytes will be non-null. If messageBytes is non-null, then
   * it contains the UTF-8-encoded bytes of the message. We do this to avoid converting back and
   * forth between Strings and bytes.
   */
  private final byte[] messageBytes;

  @Nullable
  private final String tag;

  private int hashCode;

  private Event(
      EventKind kind,
      @Nullable Location location,
      String message,
      @Nullable String tag,
      @Nullable FileOutErr outErr) {
    this.kind = Preconditions.checkNotNull(kind);
    this.location = location;
    this.message = Preconditions.checkNotNull(message);
    this.messageBytes = null;
    this.tag = tag;
    this.outErr = outErr;
  }

  private Event(
      EventKind kind,
      @Nullable Location location,
      byte[] messageBytes,
      @Nullable String tag,
      @Nullable FileOutErr outErr) {
    this.kind = Preconditions.checkNotNull(kind);
    this.location = location;
    this.message = null;
    this.messageBytes = Preconditions.checkNotNull(messageBytes);
    this.tag = tag;
    this.outErr = outErr;
  }

  public Event withTag(String tag) {
    if (Objects.equals(tag, this.tag)) {
      return this;
    }
    if (this.message != null) {
      return new Event(this.kind, this.location, this.message, tag, this.outErr);
    } else {
      return new Event(this.kind, this.location, this.messageBytes, tag, this.outErr);
    }
  }

  public Event withStdoutStderr(FileOutErr outErr) {
    if (this.message != null) {
      return new Event(this.kind, this.location, this.message, this.tag, outErr);
    } else {
      return new Event(this.kind, this.location, this.messageBytes, this.tag, outErr);
    }
  }

  public String getMessage() {
    return message != null ? message : new String(messageBytes, UTF_8);
  }

  public byte[] getMessageBytes() {
    return messageBytes != null ? messageBytes : message.getBytes(UTF_8);
  }

  /** Provide the message as a reference object. */
  public OutputReference getMessageReference() {
    // The message is short and we have it in memory anyway; so just wrap it into
    // the common interface.
    return new ArrayOutputReference(getMessageBytes());
  }

  public EventKind getKind() {
    return kind;
  }

  /**
   * the tag is typically the action that generated the event.
   */
  @Nullable
  public String getTag() {
    return tag;
  }

  /** Indicate if any output is associated with this event. */
  public boolean hasStdoutStderr() {
    return outErr != null;
  }

  /**
   * Get the stdout bytes associated with this event; typically, the event will report where the
   * output originated from.
   */
  @Nullable
  public String getStdOut() {
    if (outErr == null) {
      return null;
    }
    return outErr.outAsLatin1();
  }

  /**
   * Get the stdout bytes associated with this event; typically, the event will report where the
   * output originated from.
   */
  @Nullable
  public String getStdErr() {
    if (outErr == null) {
      return null;
    }
    return outErr.errAsLatin1();
  }

  /** Get a reference to the associated output. */
  public OutputReference getStdOutReference() {
    return outErr.getOutReference();
  }

  /** Get a reference to the associated output. */
  public OutputReference getStdErrReference() {
    return outErr.getErrReference();
  }

  /**
   * Returns the location of this event, if any.  Returns null iff the event
   * wasn't associated with any particular location, for example, a progress
   * message.
   */
  @Nullable public Location getLocation() {
    return location;
  }

  /**
   * Returns <i>some</i> moderately sane representation of the event. Should never be used in
   * user-visible places, only for debugging and testing.
   */
  @Override
  public String toString() {
    return kind + " " + (location != null ? location.print() : "<no location>") + ": "
        + getMessage();
  }

  @Override
  public int hashCode() {
    // We defer the computation of hashCode until it is needed to avoid the overhead of computing it
    // and then never using it. In particular, we use Event for streaming stdout and stderr, which
    // are both large and the hashCode is never used.
    //
    // This uses the same construction as String.hashCode. We don't lock, so reads and writes to the
    // field can race. However, integer reads and writes are atomic, and this code guarantees that
    // all writes have the same value, so the memory location can only be either 0 or the final
    // value. Note that a reader could see the final value on the first read and 0 on the second
    // read, so we must take care to only read the field once.
    int h = hashCode;
    if (h == 0) {
      h = Objects.hash(kind, location, message, tag, Arrays.hashCode(messageBytes), outErr);
      hashCode = h;
    }
    return h;
  }

  @Override
  public boolean equals(Object other) {
    if (other == this) {
      return true;
    }
    if (other == null || !other.getClass().equals(getClass())) {
      return false;
    }
    Event that = (Event) other;
    return Objects.equals(this.kind, that.kind)
        && Objects.equals(this.location, that.location)
        && Objects.equals(this.tag, that.tag)
        && Objects.equals(this.message, that.message)
        && Objects.equals(this.outErr, that.outErr)
        && Arrays.equals(this.messageBytes, that.messageBytes);
  }

  /**
   * Replay a sequence of events on an {@link EventHandler}.
   */
  public static void replayEventsOn(EventHandler eventHandler, Iterable<Event> events) {
    for (Event event : events) {
      eventHandler.handle(event);
    }
  }

  public static Event of(EventKind kind, @Nullable Location location, String message) {
    return new Event(kind, location, message, null, null);
  }

  /**
   * Construct an event by passing in the {@code byte[]} array instead of a String.
   *
   * The bytes must be decodable as UTF-8 text.
   */
  public static Event of(EventKind kind, @Nullable Location location, byte[] messageBytes) {
    return new Event(kind, location, messageBytes, null, null);
  }

  /** Reports an error. */
  public static Event error(@Nullable Location location, String message) {
    return new Event(EventKind.ERROR, location, message, null, null);
  }

  /** Reports an error. */
  public static Event error(String message) {
    return error(null, message);
  }

  /** Reports a warning. */
  public static Event warn(@Nullable Location location, String message) {
    return new Event(EventKind.WARNING, location, message, null, null);
  }

  /** Reports a warning. */
  public static Event warn(String message) {
    return warn(null, message);
  }

  /**
   * Reports atemporal statements about the build, i.e. they're true for the duration of execution.
   */
  public static Event info(@Nullable Location location, String message) {
    return new Event(EventKind.INFO, location, message, null, null);
  }

  /**
   * Reports atemporal statements about the build, i.e. they're true for the duration of execution.
   */
  public static Event info(String message) {
    return info(null, message);
  }

  /** Reports a temporal statement about the build. */
  public static Event progress(@Nullable Location location, String message) {
    return new Event(EventKind.PROGRESS, location, message, null, null);
  }

  /** Reports a temporal statement about the build. */
  public static Event progress(String message) {
    return progress(null, message);
  }

  /** Reports a debug message. */
  public static Event debug(@Nullable Location location, String message) {
    return new Event(EventKind.DEBUG, location, message, null, null);
  }

  /**
   * Reports a debug message.
   */
  public static Event debug(String message) {
    return debug(null, message);
  }

  private static class ArrayOutputReference implements OutputReference {
    private final byte[] message;

    ArrayOutputReference(byte[] message) {
      this.message = message;
    }

    @Override
    public long getLength() {
      return message.length;
    }

    @Override
    public byte[] getFinalBytes(int count) {
      if (count >= message.length) {
        return message;
      } else {
        return Arrays.copyOfRange(message, message.length - count, message.length);
      }
    }
  }
}
