// file: $isip/class/asr/Identifier/ident_02.cc
//

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


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

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

  // output the class name
  //
  if (level_a > Integral::NONE) {
    SysString 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(); 
  }

  // declare some identifiers
  //
  String database(L"Timit");
  String anchor(L"Anchor");
  String annotation(L"Annotation");  
  Identifier ident_00(database, anchor);
  Identifier ident_01(database, annotation);

  // test the register id methods
  //
  if (!ident_00.registerId().eq(L"Timit:Anchor1")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!ident_01.registerId().eq(L"Timit:Annotation1")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  if (!ident_00.registerId().eq(L"Timit:Anchor2")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!ident_01.registerId().eq(L"Timit:Annotation2")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  if (!ident_00.registerId(L"Timit:Anchor3").eq(L"Timit:Anchor3")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!ident_01.registerId(L"Timit:Annotation3").eq(L"Timit:Annotation3")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  if (!ident_00.registerId(L"Timit:Anchor3").eq(L"Timit:Anchor4")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!ident_01.registerId(L"Timit:Annotation3").eq(L"Timit:Annotation4")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }        

  // test the identifier exists method
  //
  if (!ident_00.existsId(L"Timit:Anchor1")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!ident_01.existsId(L"Timit:Annotation1")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  if (ident_00.existsId(L"Timit:Anchor8")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (ident_01.existsId(L"Timit:Annotation8")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }    

  // test the identifier reclaim method
  //
  if (!ident_00.reclaimId(L"Timit:Anchor1")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!ident_01.reclaimId(L"Timit:Annotation1")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  if (ident_00.existsId(L"Timit:Anchor1")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (ident_01.existsId(L"Timit:Annotation1")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  // test the namespace method
  //
  if (!ident_00.getNamespace(L"Timit:Anchor1").eq(L"Timit")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!ident_00.getNamespace(L"Anchor1").eq(String::EMPTY)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  // test the get/set/delete/exists annotation methods
  //
  Annotation anno_00;
  Annotation anno_01;

  ident_00.addAnnotationRef(L"Timit:Annotation1", &anno_00);
  ident_01.addAnnotationRef(L"Timit:Annotation2", &anno_01);

  if (ident_00.getAnnotationRef(L"Timit:Annotation1") != &anno_00) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (ident_01.getAnnotationRef(L"Timit:Annotation2") != &anno_01) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  if (!ident_01.existsAnnotation(L"Timit:Annotation2")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (ident_01.existsAnnotation(L"Timit:Annotation6")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  ident_01.deleteAnnotationRef(L"Timit:Annotation2");
  if (ident_01.existsAnnotation(L"Timit:Annotation2")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (ident_01.getAnnotationRef(L"Timit:Annotation2") != (Annotation*)NULL) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // test the get/set/delete/exists anchor methods
  //
  Anchor ancr_00;
  Anchor ancr_01;

  ident_00.addAnchorRef(L"Timit:Anchor1", &ancr_00);
  ident_01.addAnchorRef(L"Timit:Anchor2", &ancr_01);

  if (ident_00.getAnchorRef(L"Timit:Anchor1") != &ancr_00) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (ident_01.getAnchorRef(L"Timit:Anchor2") != &ancr_01) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  if (!ident_01.existsAnchor(L"Timit:Anchor2")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (ident_01.existsAnchor(L"Timit:Anchor6")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  ident_01.deleteAnchorRef(L"Timit:Anchor2");
  if (ident_01.existsAnchor(L"Timit:Anchor2")) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (ident_01.getAnchorRef(L"Timit:Anchor2") != (Anchor*)NULL) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  
  
  // reset indentation
  //
  if (level_a > Integral::NONE) {
    Console::decreaseIndention();
  }

  //---------------------------------------------------------------------
  //
  // 2. print completion message
  //
  //---------------------------------------------------------------------  

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

  // exit gracefully
  //
  return true;
}
