#include <iostream>
#include <sstream>

#include "TracerWithHistory.h"

using std::cout;
using std::endl;
using std::ostream;
using std::string;
using std::stringstream;
using std::vector;

TracerH::TracerH(): id_(TracerH::nextid_++) {
  history_.push_back(id_);
  cout << "Tracer(" << Print() << ")" << endl;
}

TracerH::~TracerH() {
  cout << "~Tracer(" << Print() << ")" << endl;
}

TracerH::TracerH(const TracerH &rhs): id_(TracerH::nextid_++) {
  history_.push_back(id_);
  history_.insert(history_.end(), rhs.history_.begin(), rhs.history_.end());
  cout << "TracerCopy({" << Print();
  cout << "}<--{" << rhs.Print() << "})" << endl;
}

TracerH &TracerH::operator=(const TracerH &rhs) {
  history_.insert(history_.end(), rhs.history_.begin(), rhs.history_.end());
  cout << "TracerOp=({" << Print() << "}={" << rhs.Print() << "})" << endl;
  return *this;
}

bool TracerH::operator<(const TracerH &rhs) const {
  cout << "Op< : {" << Print() << "}<{" << rhs.Print() << "}" << endl;
  return history_.back() < rhs.history_.back();
}

string TracerH::Print(void) const {
  stringstream ss;
  string open("id:"), spacer(" val:["), close("]");

  ss << open << id_ << spacer;
  for (auto i = history_.begin(); i != history_.end(); ++i) {
    if (i != history_.begin()) {
      ss << ",";
    }
    ss << *i;
  }
  ss << close;
  
  return ss.str();
}

ostream &operator<<(ostream &out, const TracerH &rhs) {
  out << rhs.Print();
  return out;
}

int TracerH::nextid_ = 0;