// file: $isip/class/asr/AudioDatabase/audb_02.cc
// version: $Id: audb_02.cc 9098 2003-04-18 21:16:04Z parihar $
//

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

// method: diagnose
//
// arguments:
//  Integral::DEBUG level: (input) debug level for diagnostics
//
// return: a boolean value indicating status
//
boolean AudioDatabase::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(); 
  }

  AudioDatabase audb_00;

  // test the get/set database name methods
  //
  String name_00(L"TIDIGITS");
  String name_01(L"TIMIT");  
  /*
  audb_00.setDataBaseName(name_00);

  if (audb_00.getDataBaseName().eq(name_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!audb_00.getDataBaseName().eq(name_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  // test the insert/get record methods
  //
  String key_00(L"key_00");
  String key_01(L"key_01");
  String key_02(L"key_02");
  String key_03(L"key_03");

  Filename audio_00(L"audio_00.raw");
  Filename audio_01(L"audio_01.raw");
  Filename audio_02(L"audio_02.raw");
  Filename audio_03(L"audio_03.raw");    

  audb_00.insertRecord(key_00, audio_00);
  audb_00.insertRecord(key_01, audio_01);
  audb_00.insertRecord(key_02, audio_02);
  audb_00.insertRecord(key_03, audio_03);  

  Filename value;

  audb_00.getRecord(key_00, value);
  if (!value.eq(audio_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  audb_00.getRecord(key_01, value);  
  if (!value.eq(audio_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  audb_00.getRecord(key_02, value);  
  if (!value.eq(audio_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  audb_00.getRecord(key_03, value);  
  if (!value.eq(audio_03)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  // test the remove/get record methods
  //
  audb_00.removeRecord(key_00);
  audb_00.removeRecord(key_01);

  if (audb_00.getRecord(key_00, value)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  if (audb_00.getRecord(key_01, value)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  audb_00.getRecord(key_02, value);  
  if (!value.eq(audio_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  audb_00.getRecord(key_03, value);  
  if (!value.eq(audio_03)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  
  */  
  // reset indentation
  //
  if (level_a > Integral::NONE) {
    Console::decreaseIndention();
  }
  
  //---------------------------------------------------------------------
  //
  // 2. test the i/o methods
  //
  //---------------------------------------------------------------------

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

  AudioDatabase audb_01;
  AudioDatabase audb_02;  

  // we need binary and text sof files
  //
  String tmp_filename0;
  Integral::makeTemp(tmp_filename0);
  String tmp_filename1;
  Integral::makeTemp(tmp_filename1);
  
  // open files in write mode
  //
  Sof tmp_file0;
  tmp_file0.open(tmp_filename0, File::WRITE_ONLY, File::TEXT);
  Sof tmp_file1;
  tmp_file1.open(tmp_filename1, File::WRITE_ONLY, File::BINARY);

  audb_00.write(tmp_file0, (long)0);
  audb_00.write(tmp_file1, (long)0);

  // close the files
  //
  tmp_file0.close();
  tmp_file1.close();

  // open the files in read mode
  //
  tmp_file0.open(tmp_filename0);
  tmp_file1.open(tmp_filename1);

  // read the object back
  //  
  audb_01.read(tmp_file0, (long)0);
  
  if (!audb_01.eq(audb_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  audb_02.read(tmp_file1, (long)0);

  if (!audb_02.eq(audb_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // close and delete the temporary files
  //
  tmp_file0.close();
  tmp_file1.close();
    
  // test load method
  //
  Sdb id_sdb, file_sdb;
  Filename id_list_file(L"$ISIP_DEVEL/doc/examples/data/lists/train_id.sof");
  Filename file_list_file(L"$ISIP_DEVEL/doc/examples/data/lists/train_list.sof");
  id_sdb.append(id_list_file, true);
  file_sdb.append(file_list_file, true);

  // load to AudioDatabase
  //
  AudioDatabase audb_03;
  Vector<Filename> vec_file;
  audb_03.setDataBaseName(name_00);
  audb_03.load(id_sdb, file_sdb, vec_file);

  // write AudioDatabase to sof file
  //
  Sof tmp_file3;
  Filename tmp_filename3(L"audio_database.sof");
  tmp_file3.open(tmp_filename3, File::WRITE_ONLY, File::BINARY);
  audb_03.store(tmp_file3, (long)0, vec_file);
  tmp_file3.close();
	       
  // read back the sof file to AudioDatabase and compare it to original one
  //
  AudioDatabase audb_04;

  // open the database
  //
  audb_04.open(tmp_filename3);

  audb_04.read(tmp_file3, (long)0);
  if (!audb_03.eq(audb_04)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // test getRecord() method
  //
  Filename record0;
  String id0(L"ae_2789385a");
  audb_04.getRecord(id0, record0);
  if (record0.ne(L"/isip/data/exp/production/t_00011/data_preparation/train/output/ae_2789385a.sof")) {
    record0.debug(L"getRecord");
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // check all the id's for getRecord() method
  //
  id_sdb.gotoFirst();
  file_sdb.gotoFirst();
  
  Filename id;
  Filename file_name;
    
  // read the transcription file
  //
  do {

    // get id and corresponding file name
    //
    id_sdb.getName(id);
    id0.assign(id);
    file_sdb.getName(file_name);

    // test the getRecord method
    //
    audb_04.getRecord(id0, record0);
    if (record0.ne(file_name)) {
      return Error::handle(name(), L"load", Error::TEST, __FILE__, __LINE__);
    }
  } while (id_sdb.gotoNext() && file_sdb.gotoNext());

  // close the audio database
  //
  audb_04.close();
  
  if (level_a < Integral::DETAILED) {
    File::remove(tmp_filename3);
  }
  
  // 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) {
    SysString output(L"diagnostics passed for class ");
    output.concat(name());
    output.concat(L"\n");
    Console::put(output);
  }

  // exit gracefully
  //
  return true;
}
