/**
 * 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.
 */

#ifndef APACHE_HTRACE_HTRACE_HPP
#define APACHE_HTRACE_HTRACE_HPP

#include "htrace.h"

#include <string>

/**
 * The public C++ API for the HTrace native client.
 *
 * The C++ API is a wrapper around the C API.  The advantage of this is that we
 * can change the C++ API in this file without breaking binary compatibility.
 *
 * EXCEPTIONS
 * We do not use exceptions in this API.  This code should be usable by
 * libraries and applications that are using the Google C++ coding style.
 * The one case where we do use exceptions is to translate NULL pointer returns
 * on OOM into std::bad_alloc exceptions.  In general, it is extremely unlikely
 * that the size of memory allocations we are doing will produce OOM.  Most
 * C++ programs do not attempt to handle OOM anyway because of the extra code
 * complexity that would be required.  So translating this into an exception is
 * fine.
 *
 * C++11
 * This code should not require C++11.  We might add #ifdefs later to take
 * advantage of certain C++11 or later features if they are available.
 */

namespace htrace {
  class Sampler;
  class Scope;
  class Tracer;

  class SpanId {
  public:
    SpanId() {
      id_.low = 0;
      id_.high = 0;
    }

    SpanId(uint64_t high, uint64_t low) {
      id_.high = high;
      id_.low = low;
    }

    SpanId(const struct htrace_span_id *other) {
      id_.high = other->high;
      id_.low = other->low;
    }

    SpanId(const SpanId &other) {
      id_.high = other.id_.high;
      id_.low = other.id_.low;
    }

    /**
     * Convert an input string into a span id.
     *
     * @param input             The input string.
     *
     * @return                  The empty string, if parsing was successful.  A
     *                          failure error message, if parsing failed.
     *                          If parsing is successful the current ID object
     *                          will be modified.
     */
    std::string FromString(const std::string &input) {
      char err[512];
      err[0] = '\0';
      htrace_span_id_parse(&id_, input.c_str(), err, sizeof(err));
      if (err[0]) {
        return std::string(err);
      }
      return "";
    }

    SpanId &operator=(const SpanId &other) {
      id_.high = other.id_.high;
      id_.low = other.id_.low;
      return *this;
    }

    bool operator<(const SpanId &other) const {
      return (htrace_span_id_compare(&id_, &other.id_) < 0);
    }

    bool operator==(const SpanId &other) const {
      return ((id_.high == other.id_.high) &&
          (id_.low == other.id_.low));
    }

    bool operator!=(const SpanId &other) const {
      return (!((*this) == other));
    }

    uint64_t GetHigh() {
      return id_.high;
    }

    void SetHigh(uint64_t high) {
      id_.high = high;
    }

    uint64_t GetLow() {
      return id_.low;
    }

    void SetLow(uint64_t low) {
      id_.low = low;
    }

    void Clear() {
      htrace_span_id_clear(&id_);
    }

    /**
     * Convert the SpanId to a human-readable string.
     */
    std::string ToString() const {
      char str[HTRACE_SPAN_ID_STRING_LENGTH + 1];
      if (!htrace_span_id_to_str(&id_, str, sizeof(str))) {
        // This should not happen, because the buffer we supplied is long
        // enough.
        return "(error converting ID to string)";
      }
      return std::string(str);
    }

  private:
    struct htrace_span_id id_;
  };

  std::ostream &operator<<(std::ostream &oss, const SpanId &spanId) {
    oss << spanId.ToString();
    return oss;
  }

  /**
   * An HTrace Configuration object.
   *
   * Configurations are thread-safe.  They can be used by multiple threads
   * simultaneously.
   */
  class Conf {
  public:
    /**
     * Create a new HTrace Conf.
     *
     * @param values    A configuration string containing a series of
     *                  semicolon-separated key=value entries.
     *                  We do not hold on to a reference to this string.
     * @param defaults  Another semicolon-separated set of key=value entries.
     *                  The defaults to be used when there is no corresponding
     *                  value in 'values.' We do not hold on to a reference to
     *                  this string.
     */
    Conf(const char *values)
      : conf_(htrace_conf_from_str(values))
    {
      if (!conf_) {
        throw std::bad_alloc();
      }
    }

    Conf(const std::string &values)
      : conf_(htrace_conf_from_str(values.c_str()))
    {
      if (!conf_) {
        throw std::bad_alloc();
      }
    }

    ~Conf() {
      htrace_conf_free(conf_);
      conf_ = NULL;
    }

  private:
    friend class Tracer;
    friend class Sampler;
    Conf &operator=(Conf &other); // Can't copy
    Conf(Conf &other);
    struct htrace_conf *conf_;
  };

  /**
   * An HTrace context object.
   *
   * Contexts are thread-safe.  They can be used by multiple threads simultaneoy
   * Most applications will not need more than one HTrace context, which is
   * often global (or at least widely used.)
   */
  class Tracer {
  public:
    /**
     * Create a new Tracer.
     *
     * @param name    The name of the tracer to create.  We do not hold on to a
     *                  reference to this string.
     * @param conf    The configuration to use for the new tracer.  We do not
     *                  hold on to a reference to this configuration.
     */
    Tracer(const std::string &name, const Conf &conf)
      : tracer_(htracer_create(name.c_str(), conf.conf_))
    {
      if (!tracer_) {
        throw std::bad_alloc();
      }
    }

    std::string Name() {
      return std::string(htracer_tname(tracer_));
    }

    /**
     * Free the Tracer.
     *
     * This destructor must not be called until all the other objects which hold
     * a reference (such as samplers and trace scopes) are freed.  It is often
     * not necessary to destroy this object at all unless you are writing a
     * library and want to support unloading your library, or you are writing an
     * application and want to support some kind of graceful shutdown.
     *
     * We could make this friendlier with some kind of reference counting via
     * atomic variables, but only at the cost of reduced performance.
     */
    ~Tracer() {
      htracer_free(tracer_);
      tracer_ = NULL;
    }

  private:
    friend class Sampler;
    friend class Scope;
    Tracer(const Tracer &other); // Can't copy
    const Tracer &operator=(const Tracer &other);
    struct htracer *tracer_;
  };

  /**
   * An HTrace sampler.
   *
   * Samplers determine when new spans are created.
   * See htrace.h for more information.
   *
   * Samplers are thread-safe.  They can be used by multiple threads
   * simultaneously.
   */
  class Sampler {
  public:
    /**
     * Create a new Sampler.
     *
     * @param tracer  The tracer to use.  You must not free this tracer until
     *                  after this sampler is freed.
     * @param conf    The configuration to use for the new sampler.  We do not
     *                  hold on to a reference to this configuration.
     */
    Sampler(Tracer *tracer, const Conf &conf)
        : smp_(htrace_sampler_create(tracer->tracer_, conf.conf_)) {
      if (!smp_) {
        throw std::bad_alloc();
      }
    }

    /**
     * Get a description of this Sampler.
     */
    std::string ToString() {
      return std::string(htrace_sampler_to_str(smp_));
    }

    ~Sampler() {
      htrace_sampler_free(smp_);
      smp_ = NULL;
    }

  private:
    friend class Tracer;
    friend class Scope;
    Sampler(const Sampler &other); // Can't copy
    const Sampler &operator=(const Sampler &other);

    struct htrace_sampler *smp_;
  };

  class Scope {
  public:
    Scope(Tracer &tracer, const char *name)
      : scope_(htrace_start_span(tracer.tracer_, NULL, name)) {
    }

    Scope(Tracer &tracer, const std::string &name)
      : scope_(htrace_start_span(tracer.tracer_, NULL, name.c_str())) {
    }

    Scope(Tracer &tracer, Sampler &smp, const char *name)
      : scope_(htrace_start_span(tracer.tracer_, smp.smp_, name)) {
    }

    Scope(Tracer &tracer, Sampler &smp, const std::string &name)
      : scope_(htrace_start_span(tracer.tracer_, smp.smp_, name.c_str())) {
    }

    ~Scope() {
      htrace_scope_close(scope_);
      scope_ = NULL;
    }

    SpanId GetSpanId() const {
      htrace_span_id id;
      htrace_scope_get_span_id(scope_, &id);
      return SpanId(&id);
    }

  private:
    friend class Tracer;
    Scope(htrace::Scope &other); // Can't copy
    Scope& operator=(Scope &scope); // Can't assign

    struct htrace_scope *scope_;
  };
}

#endif

// vim: ts=2:sw=2:et
