// file: $isip/class/algo/Recipe/rcp_02.cc
// version: $Id: rcp_02.cc 9061 2003-04-01 02:06:52Z duncan $
//

// isip include files
//
#include <Console.h>
#include "Recipe.h"

// method: diagnose
//
// arguments:
//  Integral::DEBUG level: (input) debug level for diagnostics
//
// return: a boolean value indicating status
//
boolean Recipe::diagnose(Integral::DEBUG level_a) {

  //---------------------------------------------------------------------------
  //
  // 0. preliminaries
  //
  //---------------------------------------------------------------------------

  // output the class name
  //
  if (level_a > Integral::NONE) {
    String output(L"diagnosing class ");
    output.concat(CLASS_NAME);
    output.concat(L": ");
    Console::put(output);
    Console::increaseIndention();
  } 

  //---------------------------------------------------------------------------
  //
  // 1. required public methods
  //
  //---------------------------------------------------------------------------

  // set indentation
  //
  if (level_a > Integral::NONE) {
    Console::put(L"testing required public methods...\n");
    Console::increaseIndention();
  }

  // test destructor/constructor(s) and memory management
  //
  Recipe pool0;
  Recipe pool1(pool0);
  Recipe pool2;
  
  if (!pool1.eq(pool0)) {
    return Error::handle(name(), L"copy constructor", Error::TEST,
			 __FILE__, __LINE__);
  }
  
  if (!pool2.eq(pool0)) {
    return Error::handle(name(), L"copy constructor", Error::TEST,
			 __FILE__, __LINE__);
  }

  // reset indentation
  //
  if (level_a > Integral::NONE) {
    Console::decreaseIndention();
  }
  
  //---------------------------------------------------------------------------
  //
  // 2. class-specific public methods:
  //     operation methods
  //
  //---------------------------------------------------------------------------

  // set indentation
  //
  if (level_a > Integral::NONE) {
    Console::put(L"testing class-specific public methods...\n");
    Console::increaseIndention();
  }

  // declare local variables
  //
  Sof sof;
  sof.open(L"diagnose_recipe.sof");

  Recipe pool;
  pool.setDebug(level_a);

  pool.readGraph(sof);

  sof.close();

  sof.open(L"diagnose_output.sof", File::WRITE_ONLY);
  pool.recipe_d.write(sof, 0);
  sof.close();
  
  {
    sof.open(L"diagnose_filter.sof");
    Recipe pool;
    pool.readGraph(sof);
    sof.close();

    sof.open(L"diagnose_filter_01.sof");
    SingleLinkedList<Component> algos(DstrBase::SYSTEM);
    SingleLinkedList< Triple< Pair<Long, Long>, Float, Boolean> > topo;
    algos.read(sof, 0);
    topo.read(sof, 0);

    DiGraph<Component> expected;
    expected.assign(algos, topo);

    if (!pool.recipe_d.eq(expected)) {
      expected.debug(L"expected");
      pool.recipe_d.debug(L"pool");
    }
    sof.close();
  }
  
  {
    sof.open(L"diagnose_container.sof");
    Recipe pool;
    pool.readGraph(sof);
    sof.close();

    sof.open(L"diagnose_container_01.sof");
    SingleLinkedList<Component> algos(DstrBase::SYSTEM);
    SingleLinkedList< Triple< Pair<Long, Long>, Float, Boolean> > topo;

    algos.read(sof, 0);
    topo.read(sof, 0);
    
    DiGraph<Component> expected;
    expected.assign(algos, topo);

    sof.close();
    
    if (!pool.recipe_d.eq(expected)) {
      expected.debug(L"expected");
      pool.recipe_d.debug(L"pool");
    }
  }
  
  // reset indentation
  //
  if (level_a > Integral::NONE) {
    Console::decreaseIndention();
  }
  
  //---------------------------------------------------------------------------
  //
  // 3. print completion message
  //
  //---------------------------------------------------------------------------

  // reset indentation
  //
  if (level_a > Integral::NONE) {
    Console::decreaseIndention();
  }
  
  if (level_a > Integral::NONE) {
    String output(L"diagnostics passed for class ");
    output.concat(name());
    output.concat(L"\n");
    Console::put(output);
  }
  
  // exit gracefully
  //
  return true;
}
