/**
 * Autogenerated by Thrift Compiler (0.14.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
#ifndef zipkincore_TYPES_H
#define zipkincore_TYPES_H

#include <iosfwd>

#include <thrift/Thrift.h>
#include <thrift/TApplicationException.h>
#include <thrift/TBase.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/transport/TTransport.h>

#include <functional>
#include <memory>


namespace twitter { namespace zipkin { namespace thrift {

struct AnnotationType {
  enum type {
    BOOL = 0,
    BYTES = 1,
    I16 = 2,
    I32 = 3,
    I64 = 4,
    DOUBLE = 5,
    STRING = 6
  };
};

extern const std::map<int, const char*> _AnnotationType_VALUES_TO_NAMES;

std::ostream& operator<<(std::ostream& out, const AnnotationType::type& val);

std::string to_string(const AnnotationType::type& val);

class Endpoint;

class Annotation;

class BinaryAnnotation;

class Span;

class Response;

typedef struct _Endpoint__isset {
  _Endpoint__isset() : ipv4(false), port(false), service_name(false), ipv6(false) {}
  bool ipv4 :1;
  bool port :1;
  bool service_name :1;
  bool ipv6 :1;
} _Endpoint__isset;

/**
 * Indicates the network context of a service recording an annotation with two
 * exceptions.
 * 
 * When a BinaryAnnotation, and key is CLIENT_ADDR or SERVER_ADDR,
 * the endpoint indicates the source or destination of an RPC. This exception
 * allows zipkin to display network context of uninstrumented services, or
 * clients such as web browsers.
 */
class Endpoint : public virtual ::apache::thrift::TBase {
 public:

  Endpoint(const Endpoint&);
  Endpoint& operator=(const Endpoint&);
  Endpoint() : ipv4(0), port(0), service_name(), ipv6() {
  }

  virtual ~Endpoint() noexcept;
  /**
   * IPv4 host address packed into 4 bytes.
   * 
   * Ex for the ip 1.2.3.4, it would be (1 << 24) | (2 << 16) | (3 << 8) | 4
   */
  int32_t ipv4;
  /**
   * IPv4 port
   * 
   * Note: this is to be treated as an unsigned integer, so watch for negatives.
   * 
   * Conventionally, when the port isn't known, port = 0.
   */
  int16_t port;
  /**
   * Service name in lowercase, such as "memcache" or "zipkin-web"
   * 
   * Conventionally, when the service name isn't known, service_name = "unknown".
   */
  std::string service_name;
  /**
   * IPv6 host address packed into 16 bytes. Ex Inet6Address.getBytes()
   */
  std::string ipv6;

  _Endpoint__isset __isset;

  void __set_ipv4(const int32_t val);

  void __set_port(const int16_t val);

  void __set_service_name(const std::string& val);

  void __set_ipv6(const std::string& val);

  bool operator == (const Endpoint & rhs) const
  {
    if (!(ipv4 == rhs.ipv4))
      return false;
    if (!(port == rhs.port))
      return false;
    if (!(service_name == rhs.service_name))
      return false;
    if (__isset.ipv6 != rhs.__isset.ipv6)
      return false;
    else if (__isset.ipv6 && !(ipv6 == rhs.ipv6))
      return false;
    return true;
  }
  bool operator != (const Endpoint &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Endpoint & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(Endpoint &a, Endpoint &b);

std::ostream& operator<<(std::ostream& out, const Endpoint& obj);

typedef struct _Annotation__isset {
  _Annotation__isset() : timestamp(false), value(false), host(false) {}
  bool timestamp :1;
  bool value :1;
  bool host :1;
} _Annotation__isset;

/**
 * An annotation is similar to a log statement. It includes a host field which
 * allows these events to be attributed properly, and also aggregatable.
 */
class Annotation : public virtual ::apache::thrift::TBase {
 public:

  Annotation(const Annotation&);
  Annotation& operator=(const Annotation&);
  Annotation() : timestamp(0), value() {
  }

  virtual ~Annotation() noexcept;
  /**
   * Microseconds from epoch.
   * 
   * This value should use the most precise value possible. For example,
   * gettimeofday or syncing nanoTime against a tick of currentTimeMillis.
   */
  int64_t timestamp;
  std::string value;
  /**
   * Always the host that recorded the event. By specifying the host you allow
   * rollup of all events (such as client requests to a service) by IP address.
   */
  Endpoint host;

  _Annotation__isset __isset;

  void __set_timestamp(const int64_t val);

  void __set_value(const std::string& val);

  void __set_host(const Endpoint& val);

  bool operator == (const Annotation & rhs) const
  {
    if (!(timestamp == rhs.timestamp))
      return false;
    if (!(value == rhs.value))
      return false;
    if (__isset.host != rhs.__isset.host)
      return false;
    else if (__isset.host && !(host == rhs.host))
      return false;
    return true;
  }
  bool operator != (const Annotation &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Annotation & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(Annotation &a, Annotation &b);

std::ostream& operator<<(std::ostream& out, const Annotation& obj);

typedef struct _BinaryAnnotation__isset {
  _BinaryAnnotation__isset() : key(false), value(false), annotation_type(false), host(false) {}
  bool key :1;
  bool value :1;
  bool annotation_type :1;
  bool host :1;
} _BinaryAnnotation__isset;

/**
 * Binary annotations are tags applied to a Span to give it context. For
 * example, a binary annotation of "http.uri" could the path to a resource in a
 * RPC call.
 * 
 * Binary annotations of type STRING are always queryable, though more a
 * historical implementation detail than a structural concern.
 * 
 * Binary annotations can repeat, and vary on the host. Similar to Annotation,
 * the host indicates who logged the event. This allows you to tell the
 * difference between the client and server side of the same key. For example,
 * the key "http.uri" might be different on the client and server side due to
 * rewriting, like "/api/v1/myresource" vs "/myresource. Via the host field,
 * you can see the different points of view, which often help in debugging.
 */
class BinaryAnnotation : public virtual ::apache::thrift::TBase {
 public:

  BinaryAnnotation(const BinaryAnnotation&);
  BinaryAnnotation& operator=(const BinaryAnnotation&);
  BinaryAnnotation() : key(), value(), annotation_type((AnnotationType::type)0) {
  }

  virtual ~BinaryAnnotation() noexcept;
  std::string key;
  std::string value;
  /**
   * 
   * @see AnnotationType
   */
  AnnotationType::type annotation_type;
  /**
   * The host that recorded tag, which allows you to differentiate between
   * multiple tags with the same key. There are two exceptions to this.
   * 
   * When the key is CLIENT_ADDR or SERVER_ADDR, host indicates the source or
   * destination of an RPC. This exception allows zipkin to display network
   * context of uninstrumented services, or clients such as web browsers.
   */
  Endpoint host;

  _BinaryAnnotation__isset __isset;

  void __set_key(const std::string& val);

  void __set_value(const std::string& val);

  void __set_annotation_type(const AnnotationType::type val);

  void __set_host(const Endpoint& val);

  bool operator == (const BinaryAnnotation & rhs) const
  {
    if (!(key == rhs.key))
      return false;
    if (!(value == rhs.value))
      return false;
    if (!(annotation_type == rhs.annotation_type))
      return false;
    if (__isset.host != rhs.__isset.host)
      return false;
    else if (__isset.host && !(host == rhs.host))
      return false;
    return true;
  }
  bool operator != (const BinaryAnnotation &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const BinaryAnnotation & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(BinaryAnnotation &a, BinaryAnnotation &b);

std::ostream& operator<<(std::ostream& out, const BinaryAnnotation& obj);

typedef struct _Span__isset {
  _Span__isset() : trace_id(false), name(false), id(false), parent_id(false), annotations(false), binary_annotations(false), debug(true), timestamp(false), duration(false), trace_id_high(false) {}
  bool trace_id :1;
  bool name :1;
  bool id :1;
  bool parent_id :1;
  bool annotations :1;
  bool binary_annotations :1;
  bool debug :1;
  bool timestamp :1;
  bool duration :1;
  bool trace_id_high :1;
} _Span__isset;

/**
 * A trace is a series of spans (often RPC calls) which form a latency tree.
 * 
 * The root span is where trace_id = id and parent_id = Nil. The root span is
 * usually the longest interval in the trace, starting with a SERVER_RECV
 * annotation and ending with a SERVER_SEND.
 */
class Span : public virtual ::apache::thrift::TBase {
 public:

  Span(const Span&);
  Span& operator=(const Span&);
  Span() : trace_id(0), name(), id(0), parent_id(0), debug(false), timestamp(0), duration(0), trace_id_high(0) {
  }

  virtual ~Span() noexcept;
  int64_t trace_id;
  /**
   * Span name in lowercase, rpc method for example
   * 
   * Conventionally, when the span name isn't known, name = "unknown".
   */
  std::string name;
  int64_t id;
  int64_t parent_id;
  std::vector<Annotation>  annotations;
  std::vector<BinaryAnnotation>  binary_annotations;
  bool debug;
  /**
   * Microseconds from epoch of the creation of this span.
   * 
   * This value should be set directly by instrumentation, using the most
   * precise value possible. For example, gettimeofday or syncing nanoTime
   * against a tick of currentTimeMillis.
   * 
   * For compatibility with instrumentation that precede this field, collectors
   * or span stores can derive this via Annotation.timestamp.
   * For example, SERVER_RECV.timestamp or CLIENT_SEND.timestamp.
   * 
   * This field is optional for compatibility with old data: first-party span
   * stores are expected to support this at time of introduction.
   */
  int64_t timestamp;
  /**
   * Measurement of duration in microseconds, used to support queries.
   * 
   * This value should be set directly, where possible. Doing so encourages
   * precise measurement decoupled from problems of clocks, such as skew or NTP
   * updates causing time to move backwards.
   * 
   * For compatibility with instrumentation that precede this field, collectors
   * or span stores can derive this by subtracting Annotation.timestamp.
   * For example, SERVER_SEND.timestamp - SERVER_RECV.timestamp.
   * 
   * If this field is persisted as unset, zipkin will continue to work, except
   * duration query support will be implementation-specific. Similarly, setting
   * this field non-atomically is implementation-specific.
   * 
   * This field is i64 vs i32 to support spans longer than 35 minutes.
   */
  int64_t duration;
  /**
   * Optional unique 8-byte additional identifier for a trace. If non zero, this
   * means the trace uses 128 bit traceIds instead of 64 bit.
   */
  int64_t trace_id_high;

  _Span__isset __isset;

  void __set_trace_id(const int64_t val);

  void __set_name(const std::string& val);

  void __set_id(const int64_t val);

  void __set_parent_id(const int64_t val);

  void __set_annotations(const std::vector<Annotation> & val);

  void __set_binary_annotations(const std::vector<BinaryAnnotation> & val);

  void __set_debug(const bool val);

  void __set_timestamp(const int64_t val);

  void __set_duration(const int64_t val);

  void __set_trace_id_high(const int64_t val);

  bool operator == (const Span & rhs) const
  {
    if (!(trace_id == rhs.trace_id))
      return false;
    if (!(name == rhs.name))
      return false;
    if (!(id == rhs.id))
      return false;
    if (__isset.parent_id != rhs.__isset.parent_id)
      return false;
    else if (__isset.parent_id && !(parent_id == rhs.parent_id))
      return false;
    if (!(annotations == rhs.annotations))
      return false;
    if (!(binary_annotations == rhs.binary_annotations))
      return false;
    if (__isset.debug != rhs.__isset.debug)
      return false;
    else if (__isset.debug && !(debug == rhs.debug))
      return false;
    if (__isset.timestamp != rhs.__isset.timestamp)
      return false;
    else if (__isset.timestamp && !(timestamp == rhs.timestamp))
      return false;
    if (__isset.duration != rhs.__isset.duration)
      return false;
    else if (__isset.duration && !(duration == rhs.duration))
      return false;
    if (__isset.trace_id_high != rhs.__isset.trace_id_high)
      return false;
    else if (__isset.trace_id_high && !(trace_id_high == rhs.trace_id_high))
      return false;
    return true;
  }
  bool operator != (const Span &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Span & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(Span &a, Span &b);

std::ostream& operator<<(std::ostream& out, const Span& obj);


class Response : public virtual ::apache::thrift::TBase {
 public:

  Response(const Response&);
  Response& operator=(const Response&);
  Response() : ok(0) {
  }

  virtual ~Response() noexcept;
  bool ok;

  void __set_ok(const bool val);

  bool operator == (const Response & rhs) const
  {
    if (!(ok == rhs.ok))
      return false;
    return true;
  }
  bool operator != (const Response &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Response & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(Response &a, Response &b);

std::ostream& operator<<(std::ostream& out, const Response& obj);

}}} // namespace

#endif
