/*******************************************************************************
 *
 * File:     basic-system.cpp
 *
 * Contents: A simple example on the basic System and Unit classes of the RoSA
 *           Core library.
 *
 * Copyright 2017
 *
 * Author: David Juhasz (david.juhasz@tuwien.ac.at)
 *
 ******************************************************************************/

#include "rosa/config/version.h"
#include "rosa/core/System.h"
#include "rosa/core/Unit.h"
#include "rosa/support/log.h"
#include "rosa/support/terminal_colors.h"
#include <iostream>

using namespace rosa;
using namespace rosa::terminal;

// A dummy wrapper for testing System.
// NOTE: Since we test System directly here, we need to get access to its
// protected members. That we do by imitating to be a decent subclass of
// System, while calling protected member functions on an object of a type from
// which we actually don't inherit.
struct SystemTester : protected System {
  static Unit &createMyUnit(System *S,
                            const std::string &Name = std::string()) {
    return ((SystemTester *)S)
        ->createUnit([](const size_t Id, const std::string &N,
                        System &S) { return new Unit(Id, N, S); },
                     Name);
  }

  static void destroyMyUnit(System *S, Unit &U) {
    ((SystemTester *)S)->destroyUnit(U);
  }
};

int main(void) {
  LOG_INFO_STREAM << library_string() << " -- " << Color::Red
                  << "simple example" << Color::Default << std::endl;

  std::unique_ptr<System> S = System::createSystem("Sys");
  System *SP = S.get();
  Unit &Unit1 = SystemTester::createMyUnit(SP),
       &Unit2 = SystemTester::createMyUnit(SP, "Second"),
       &Unit3 = SystemTester::createMyUnit(SP);
  SystemTester::destroyMyUnit(SP, Unit1);
  SystemTester::destroyMyUnit(SP, Unit3);
  LOG_INFO_STREAM << "Dumping Unit2" << std::endl << Unit2 << std::endl;
  SystemTester::destroyMyUnit(SP, Unit2);
  return 0;
}

