#include "catalog.h"
#include "stdio.h"

RelCatalog::RelCatalog(Status &status) :
	 HeapFile(RELCATNAME, status)
{
// nothing should be needed here
}


const Status RelCatalog::getInfo(const string & relation, RelDesc &record)
{
  if (relation.empty())
    return BADCATPARM;

  Status status;
  Record rec;
  RID rid;
  HeapFileScan *hfs = new HeapFileScan(RELCATNAME, status);
  if (status != OK) return status;
  status = hfs->startScan(0, MAXNAME, STRING, relation.c_str(), EQ);
  if (status != OK) return status;
  status = hfs->scanNext(rid);
  if (status != OK) return status;
  status = hfs->getRecord(rec);
  if (status != OK) return status;
  memcpy(&record,(RelDesc*)rec.data, rec.length);
  delete hfs;
  return OK;
}


const Status RelCatalog::addInfo(RelDesc & record)
{
  RID rid;
  InsertFileScan*  ifs;
  Status status;
  ifs = new InsertFileScan(RELCATNAME, status);
  if (status != OK) return status;
  Record rec;
  rec.data = &record;
  rec.length = sizeof(record);
  status = ifs->insertRecord(rec, rid);
  if (status != OK) return status;
  delete ifs;
  return OK;
}

const Status RelCatalog::removeInfo(const string & relation)
{
  Status status;
  RID rid;
  HeapFileScan*  hfs;

  if (relation.empty()) return BADCATPARM;
  hfs = new HeapFileScan(RELCATNAME, status);
  if (status != OK) return status;
  status = hfs->startScan(0, MAXNAME, STRING, relation.c_str(), EQ);
  if (status != OK) return status;
  status = hfs->scanNext(rid);
  if (status != OK) return status;
  status = hfs->deleteRecord();
  if (status != OK) return status;
  delete hfs;
  return OK;

}


RelCatalog::~RelCatalog()
{
// nothing should be needed here
}


AttrCatalog::AttrCatalog(Status &status) :
	 HeapFile(ATTRCATNAME, status)
{
// nothing should be needed here
}


const Status AttrCatalog::getInfo(const string & relation, 
				  const string & attrName,
				  AttrDesc &record)
{

  Status status;
  RID rid;
  Record rec;
  HeapFileScan*  hfs;

  if (relation.empty() || attrName.empty()) return BADCATPARM;
  hfs = new HeapFileScan(ATTRCATNAME, status);
  if (status != OK) return status;
  status = hfs->startScan(0, MAXNAME, STRING, relation.c_str(), EQ);
  if (status != OK) return status;
  while((status = hfs->scanNext(rid))== OK){
	status = hfs->getRecord(rec);
	if(status != OK) return status;
        memcpy(&record,(char*)rec.data, rec.length);
	if (strcmp(attrName.c_str(), record.attrName) == 0){
		return OK;
	}
  }
  delete hfs;
  return OK;

}


const Status AttrCatalog::addInfo(AttrDesc & record)
{
  RID rid;
  InsertFileScan*  ifs;
  Status status;
  ifs = new InsertFileScan(ATTRCATNAME, status);
  if (status != OK) return status;
  Record rec;
  rec.data = &record;
  rec.length = sizeof(record);
  status = ifs->insertRecord(rec, rid);
  if (status != OK) return status;
  delete ifs;
  return OK;

}


const Status AttrCatalog::removeInfo(const string & relation, 
			       const string & attrName)
{
  Status status;
  Record rec;
  RID rid;
  AttrDesc record;
  HeapFileScan*  hfs;

  if (relation.empty() || attrName.empty()) return BADCATPARM;
  hfs = new HeapFileScan(ATTRCATNAME, status);
  if (status != OK) return status;
  status = hfs->startScan(0, MAXNAME, STRING, relation.c_str(), EQ);
  if (status != OK) return status;
  while((status = hfs->scanNext(rid))== OK){
	status = hfs->getRecord(rec);
	if(status != OK) return status;
        memcpy(&record,(char*)rec.data, rec.length);
	if (strcmp(attrName.c_str(), record.attrName) == 0){
		hfs->deleteRecord();
	}
  }  
  delete hfs;
  return OK;
}


const Status AttrCatalog::getRelInfo(const string & relation, 
				     int &attrCnt,
				     AttrDesc *&attrs)
{
  Status status;
  RID rid;
  Record rec;
  HeapFileScan*  hfs;
  RelDesc rd;
  if (relation.empty()) return BADCATPARM;
  hfs = new HeapFileScan(ATTRCATNAME, status);
  if(!hfs) return INSUFMEM;

  status = relCat->getInfo(relation, rd);
  if(status != OK) return status;

  if (status != OK) return status;
  status = hfs->startScan(0, MAXNAME, STRING, relation.c_str(), EQ);
  if (status != OK) return status;
  attrs = new AttrDesc[rd.attrCnt];
  if(!attrs)	return INSUFMEM;
  attrCnt = 0;
  int index = 0;
  
  while((status = hfs->scanNext(rid))== OK){
	status = hfs->getRecord(rec);
	if(status != OK) return status;
        memcpy(&attrs[index],(char*)rec.data, rec.length);
       	attrCnt++;
	index ++;
  }
  
  delete hfs;
  return OK;

}


AttrCatalog::~AttrCatalog()
{
// nothing should be needed here
}

