/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.htrace;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.htrace.impl.MilliSpan;
import org.apache.htrace.impl.TrueIfTracingSampler;
import org.apache.htrace.wrappers.TraceCallable;
import org.apache.htrace.wrappers.TraceRunnable;

import java.util.concurrent.Callable;

/**
 * The Trace class is the primary way to interact with the library.  It provides
 * methods to create and manipulate spans.
 *
 * A 'Span' represents a length of time.  It has many other attributes such as a
 * description, ID, and even potentially a set of key/value strings attached to
 * it.
 *
 * Each thread in your application has a single currently active currentSpan
 * associated with it.  When this is non-null, it represents the current
 * operation that the thread is doing.  Spans are NOT thread-safe, and must
 * never be used by multiple threads at once.  With care, it is possible to
 * safely pass a Span object between threads, but in most cases this is not
 * necessary.
 *
 * A 'TraceScope' can either be empty, or contain a Span.  TraceScope objects
 * implement the Java's Closeable interface.  Similar to file descriptors, they
 * must be closed after they are created.  When a TraceScope contains a Span,
 * this span is closed when the scope is closed.
 *
 * The 'startSpan' methods in this class do a few things:
 * <ul>
 *   <li>Create a new Span which has this thread's currentSpan as one of its parents.</li>
 *   <li>Set currentSpan to the new Span.</li>
 *   <li>Create a TraceSpan object to manage the new Span.</li>
 * </ul>
 *
 * Closing a TraceScope does a few things:
 * <ul>
 *   <li>It closes the span which the scope was managing.</li>
 *   <li>Set currentSpan to the previous currentSpan (which may be null).</li>
 * </ul>
 */
public class Trace {
  private static final Log LOG = LogFactory.getLog(Trace.class);

  /**
   * Creates a new trace scope.
   *
   * If this thread has a currently active trace span, the trace scope we create
   * here will contain a new span descending from the currently active span.
   * If there is no currently active trace span, the trace scope we create will
   * be empty.
   *
   * @param description   The description field for the new span to create.
   */
  public static TraceScope startSpan(String description) {
    return startSpan(description, TrueIfTracingSampler.INSTANCE);
  }

  public static TraceScope startSpan(String description, TraceInfo tinfo) {
    if (tinfo == null) return continueSpan(null);
    Span newSpan = new MilliSpan.Builder().
        begin(System.currentTimeMillis()).
        end(0).
        description(description).
        traceId(tinfo.traceId).
        parents(new long[] { tinfo.spanId }).
        processId(Tracer.getProcessId()).
        build();
    return continueSpan(newSpan);
  }

  /**
   * Creates a new trace scope.
   *
   * If this thread has a currently active trace span, it must be the 'parent'
   * span that you pass in here as a parameter.  The trace scope we create here
   * will contain a new span which is a child of 'parent'.
   *
   * @param description   The description field for the new span to create.
   */
  public static TraceScope startSpan(String description, Span parent) {
    if (parent == null) {
      return startSpan(description);
    }
    Span currentSpan = currentSpan();
    if ((currentSpan != null) && (currentSpan != parent)) {
      Tracer.clientError("HTrace client error: thread " +
          Thread.currentThread().getName() + " tried to start a new Span " +
          "with parent " + parent.toString() + ", but there is already a " +
          "currentSpan " + currentSpan);
    }
    return continueSpan(parent.child(description));
  }

  public static <T> TraceScope startSpan(String description, Sampler<T> s) {
    return startSpan(description, s, null);
  }

  public static <T> TraceScope startSpan(String description, Sampler<T> s, T info) {
    Span span = null;
    if (isTracing() || s.next(info)) {
      span = Tracer.getInstance().createNew(description);
    }
    return continueSpan(span);
  }

  /**
   * Pick up an existing span from another thread.
   */
  public static TraceScope continueSpan(Span s) {
    // Return an empty TraceScope that does nothing on close
    if (s == null) return NullScope.INSTANCE;
    return Tracer.getInstance().continueSpan(s);
  }

  /**
   * Set the processId to be used for all Spans created by this Tracer.
   *
   * @see Span
   */
  public static void setProcessId(String processId) {
    Tracer.processId = processId;
  }

  /**
   * Removes the given SpanReceiver from the list of SpanReceivers.
   */
  public static void removeReceiver(SpanReceiver rcvr) {
    Tracer.getInstance().removeReceiver(rcvr);
  }

  /**
   * Adds the given SpanReceiver to the current Tracer instance's list of
   * SpanReceivers.
   */
  public static void addReceiver(SpanReceiver rcvr) {
    Tracer.getInstance().addReceiver(rcvr);
  }

  /**
   * Adds a data annotation to the current span if tracing is currently on.
   */
  public static void addKVAnnotation(byte[] key, byte[] value) {
    Span s = currentSpan();
    if (s != null) {
      s.addKVAnnotation(key, value);
    }
  }

  /**
   * Annotate the current span with the given message.
   */
  public static void addTimelineAnnotation(String msg) {
    Span s = currentSpan();
    if (s != null) {
      s.addTimelineAnnotation(msg);
    }
  }

  /**
   * Returns true if the current thread is a part of a trace, false otherwise.
   */
  public static boolean isTracing() {
    return Tracer.getInstance().isTracing();
  }

  /**
   * If we are tracing, return the current span, else null
   *
   * @return Span representing the current trace, or null if not tracing.
   */
  public static Span currentSpan() {
    return Tracer.getInstance().currentSpan();
  }

  /**
   * Wrap the callable in a TraceCallable, if tracing.
   *
   * @return The callable provided, wrapped if tracing, 'callable' if not.
   */
  public static <V> Callable<V> wrap(Callable<V> callable) {
    if (isTracing()) {
      return new TraceCallable<V>(Trace.currentSpan(), callable);
    } else {
      return callable;
    }
  }

  /**
   * Wrap the runnable in a TraceRunnable, if tracing
   *
   * @return The runnable provided, wrapped if tracing, 'runnable' if not.
   */
  public static Runnable wrap(Runnable runnable) {
    if (isTracing()) {
      return new TraceRunnable(Trace.currentSpan(), runnable);
    } else {
      return runnable;
    }
  }

  /**
   * Wrap the runnable in a TraceRunnable, if tracing
   *
   * @param description name of the span to be created.
   * @param runnable The runnable that will have tracing info associated with it if tracing.
   * @return The runnable provided, wrapped if tracing, 'runnable' if not.
   */
  public static Runnable wrap(String description, Runnable runnable) {
    if (isTracing()) {
      return new TraceRunnable(Trace.currentSpan(), runnable, description);
    } else {
      return runnable;
    }
  }
}
