// Copyright (c) 2006- Facebook
// Distributed under the Thrift Software License
//
// See accompanying file LICENSE or visit the Thrift site at:
// http://developers.facebook.com/thrift/

#ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
#define _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_ 1

#include "TProtocol.h"
#include "TOneWayProtocol.h"

#include <boost/shared_ptr.hpp>

namespace facebook { namespace thrift { namespace protocol {

/*

!!! EXPERIMENTAL CODE !!!

This protocol is very much a work in progress.
It doesn't handle many cases properly.
It throws exceptions in many cases.
It probably segfaults in many cases.
Bug reports and feature requests are welcome.
Complaints are not. :R

*/


/**
 * Protocol that prints the payload in a nice human-readable format.
 * Reading from this protocol is not supported.
 *
 * @author David Reiss <dreiss@facebook.com>
 */
class TDebugProtocol : public TWriteOnlyProtocol {
 private:
  enum write_state_t
  { UNINIT
  , STRUCT
  , LIST
  , SET
  , MAP_KEY
  , MAP_VALUE
  };

 public:
  TDebugProtocol(boost::shared_ptr<TTransport> trans)
    : TWriteOnlyProtocol(trans, "TDebugProtocol")
    , string_limit_(DEFAULT_STRING_LIMIT)
    , string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE)
  {
    write_state_.push_back(UNINIT);
  }

  static const int32_t DEFAULT_STRING_LIMIT = 256;
  static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;

  void setStringSizeLimit(int32_t string_limit) {
    string_limit_ = string_limit;
  }

  void setStringPrefixSize(int32_t string_prefix_size) {
    string_prefix_size_ = string_prefix_size;
  }


  virtual uint32_t writeMessageBegin(const std::string& name,
                                     const TMessageType messageType,
                                     const int32_t seqid);

  virtual uint32_t writeMessageEnd();


  uint32_t writeStructBegin(const char* name);

  uint32_t writeStructEnd();

  uint32_t writeFieldBegin(const char* name,
                           const TType fieldType,
                           const int16_t fieldId);

  uint32_t writeFieldEnd();

  uint32_t writeFieldStop();

  uint32_t writeMapBegin(const TType keyType,
                         const TType valType,
                         const uint32_t size);

  uint32_t writeMapEnd();

  uint32_t writeListBegin(const TType elemType,
                          const uint32_t size);

  uint32_t writeListEnd();

  uint32_t writeSetBegin(const TType elemType,
                         const uint32_t size);

  uint32_t writeSetEnd();

  uint32_t writeBool(const bool value);

  uint32_t writeByte(const int8_t byte);

  uint32_t writeI16(const int16_t i16);

  uint32_t writeI32(const int32_t i32);

  uint32_t writeI64(const int64_t i64);

  uint32_t writeDouble(const double dub);

  uint32_t writeString(const std::string& str);

  uint32_t writeBinary(const std::string& str);


 private:
  void indentUp();
  void indentDown();
  uint32_t writePlain(const std::string& str);
  uint32_t writeIndented(const std::string& str);
  uint32_t startItem();
  uint32_t endItem();
  uint32_t writeItem(const std::string& str);

  static std::string fieldTypeName(TType type);

  int32_t string_limit_;
  int32_t string_prefix_size_;

  std::string indent_str_;
  static const int indent_inc = 2;

  std::vector<write_state_t> write_state_;
  std::vector<int> list_idx_;
};

/**
 * Constructs debug protocol handlers
 */
class TDebugProtocolFactory : public TProtocolFactory {
 public:
  TDebugProtocolFactory() {}
  virtual ~TDebugProtocolFactory() {}

  boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
    return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
  }

};

}}} // facebook::thrift::protocol


// TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this.
#include <transport/TBufferTransports.h>

namespace facebook { namespace thrift {

template<typename ThriftStruct>
std::string ThriftDebugString(const ThriftStruct& ts) {
  using namespace facebook::thrift::transport;
  using namespace facebook::thrift::protocol;
  TMemoryBuffer* buffer = new TMemoryBuffer;
  boost::shared_ptr<TTransport> trans(buffer);
  TDebugProtocol protocol(trans);

  ts.write(&protocol);

  uint8_t* buf;
  uint32_t size;
  buffer->getBuffer(&buf, &size);
  return std::string((char*)buf, (unsigned int)size);
}

// TODO(dreiss): This is badly broken.  Don't use it unless you are me.
#if 0
template<typename Object>
std::string DebugString(const std::vector<Object>& vec) {
  using namespace facebook::thrift::transport;
  using namespace facebook::thrift::protocol;
  TMemoryBuffer* buffer = new TMemoryBuffer;
  boost::shared_ptr<TTransport> trans(buffer);
  TDebugProtocol protocol(trans);

  // I am gross!
  protocol.writeStructBegin("SomeRandomVector");

  // TODO: Fix this with a trait.
  protocol.writeListBegin((TType)99, vec.size());
  typename std::vector<Object>::const_iterator it;
  for (it = vec.begin(); it != vec.end(); ++it) {
    it->write(&protocol);
  }
  protocol.writeListEnd();

  uint8_t* buf;
  uint32_t size;
  buffer->getBuffer(&buf, &size);
  return std::string((char*)buf, (unsigned int)size);
}
#endif // 0

}} // facebook::thrift


#endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_


