// 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 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;

  /**
   * 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 final int hashCode;

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

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

  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);
    } else {
      return new Event(this.kind, this.location, this.messageBytes, tag);
    }
  }

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

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

  public EventKind getKind() {
    return kind;
  }

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

  /**
   * 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() {
    return hashCode;
  }

  @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)
        && 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);
  }

  /**
   * 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);
  }

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

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

  /**
   * 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);
  }

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

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

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

  /**
   * 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(String message) {
    return info(null, message);
  }

  /**
   * 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(String message) {
    return debug(null, message);
  }
}
