#include "persifs.h"
#include "fsfile.h"
#include "fsdir.h"

/* Constructor
 */
fsdir::fsdir(ref<fsfile> file, inumber parent)
  : my_file(file), my_parent(parent), entries(NULL), dot(sdot, file->getInumber()), dotdot(sdotdot, parent)
{

}

fsdir::~fsdir()
{
  if (entries) {
    entries->deleteall();
  }
}


/**
 * Create a new directory containing only . and .. entries.  This is
 * a factory function.
 */
void 
fsdir::create(ref<fsdir> parent, fattr3 fa,
                   callback<void, ref<fsdir> >::ref cb, cbe error)
{
   fsfile::create(parent->my_file->my_fs, fa, wrap(create_cb1, cb, error), error);  
}

void 
fsdir::create_cb1(callback<void, ref<fsdir> >::ref cb, cbe error, ref <fsfile> file)
{
   cb(New refcounted<fsdir>(file, file->getInumber()));
}

/**
 * Load an existing directory from a file.  This is a factory
 * function.
 */
void 
fsdir::load(ref<fsfile> file,
                   callback<void, ref<fsdir> >::ref cb, cbe error)
{
    cb(New refcounted<fsdir>(file, file->getInumber()));
}

  

void 
fsdir::lookup(str name, callback<void, fsdirEntry* >::ref cb, cbe error)
{

 if (name==sdot)
      cb(&dot);
   else if (name = sdotdot)
      cb(&dotdot);
   else
      cb((*entries)[name]);

}


void 
fsdir::add(str name, inumber num,
           callback<void>::ref cb, cbe error)
{
    fsdirEntry *e;

    e=(*entries)[name];

    if (e==NULL)
    {
       e= New fsdirEntry(name, num);
       entries->insert(e); 
       cb();
    }
    else
    {
       //is there an nfs3error for trying to create an existing file??
       cb(); 
    }
}

void 
fsdir::add(str name, ref<fsfile> file,
           callback<void>::ref cb, cbe error)
{
    inumber num=file->getInumber();
    add(name, num, cb, error);
}



/**
 * Remove an entry from this directory.  
 */
void 
fsdir::remove(str name, callback<void>::ref cb, cbe error)
{
     lookup(name, wrap(this, &fsdir::remove_cb1, cb, error), error);
}

void
fsdir::remove_cb1(callback<void>::ref cb, cbe error, fsdirEntry *e)
{
    if (e!=NULL)
    {
        entries->remove(e); 
    }
    cb();
}

const str fsdir::sdot(".");
const str fsdir::sdotdot("..");
