///////////////////////////////////////////////////////////////////////////////
///
//          STFSd_read
///
/// \brief  Reads from an STFS file
///
///////////////////////////////////////////////////////////////////////////////
ssize_t
STFSd_read(STFS_OpenIdentifier *pp_OpenId,
           void                *pp_Buf,
           size_t               pv_Count)
{
  const char     *WHERE = "STFSd_read";
  STFS_ScopeTrace lv_st(WHERE);
  STFS_Session *lp_Session = STFS_Session::GetSession();

  if(!lp_Session) {
    return -1;
  }

  if(!pp_OpenId || !pp_Buf) {
    //Invalid argument errno
    return -1;
  }

  if (pv_Count > (size_t)STFS_SSIZE_MAX) {
    return -1;
  }

  //If count is > buffer size then what? Handle this at the send.cpp level

  //Lookup Open file,  Need to have added check to see if node matches
  STFS_ExternalFileOpenerContainer *lp_EfoContainer = STFS_ExternalFileOpenerContainer::GetInstance();
  if (!lp_EfoContainer) {
    TRACE_PRINTF2(1,"%s\n", "Null EFO Container");
    return -1;
  }

  STFS_ExternalFileOpenerInfo *lp_Efoi = lp_EfoContainer->Get(pp_OpenId);
  if (!lp_Efoi) {
    TRACE_PRINTF3(1,
                  "Open Id: %d,%ld not found in the EFO Container\n",
                  pp_OpenId->sqOwningDaemonNodeId,
                  pp_OpenId->openIdentifier
                  );
    return -1;
  }
  STFS_ExternalFileMetadata *lp_Efm = lp_Efoi->efm_;
  if (!lp_Efm) {
    TRACE_PRINTF1(1,"Null EFM Found in the lp_Efoi Entry\n");
    return -1;
  }

  TraceOpeners(lp_EfoContainer,
               lp_Efm);
  

  //Check to see if the file is local

  //If not local then Don't do anything. Return 0.

  //Do Read


  return 0;
}
///////////////////////////////////////////////////////////////////////////////
///
//          STFSd_close
///
/// \brief  Processes a file close request given the open identifier
///
/// \param  STFS_OpenIdentifier *pp_OpenId
/// 
///////////////////////////////////////////////////////////////////////////////
int
STFSd_close(STFS_OpenIdentifier *pp_OpenId)
{
  const char     *WHERE = "STFSd_close";
  STFS_ScopeTrace lv_st(WHERE);

  if (!pp_OpenId) {
    return -1;
  }

  STFS_ExternalFileOpenerContainer *lp_EfoContainer = STFS_ExternalFileOpenerContainer::GetInstance();
  if (!lp_EfoContainer) {
    TRACE_PRINTF2(1,"%s\n", "Null EFO Container");
    return -1;
  }

  STFS_ExternalFileOpenerInfo *lp_Efoi = lp_EfoContainer->Get(pp_OpenId);
  if (!lp_Efoi) {
    TRACE_PRINTF3(1,
                  "Open Id: %d,%ld not found in the EFO Container\n",
                  pp_OpenId->sqOwningDaemonNodeId,
                  pp_OpenId->openIdentifier
                  );
    return -1;
  }
  STFS_ExternalFileMetadata *lp_Efm = lp_Efoi->efm_;
  if (!lp_Efm) {
    TRACE_PRINTF1(1,"Null EFM Found in the Efoi Entry\n");
    return -1;
  }

  TraceOpeners(lp_EfoContainer,
               lp_Efm);
  
  int lv_Ret = lp_Efm->Close(true);
  if (lv_Ret < 0) {
    return lv_Ret;
  }

  lv_Ret = lp_EfoContainer->Delete(pp_OpenId);
  if (lv_Ret < 0) {
    return lv_Ret;
  }

  TraceOpeners(lp_EfoContainer,
               lp_Efm);

  lv_Ret = STFS_ExternalFileMetadata::DeleteFromContainer(lp_Efm);
  if (lv_Ret < 0) {
    return lv_Ret;
  }

  return lv_Ret;
}
  int
  STFSLIB_close(stfs_fhndl_t pv_Fhandle)
  {
    const char     *WHERE = "STFSLIB_close";
    STFS_ScopeTrace lv_st(WHERE);

    STFS_ExternalFileHandle *lp_Efh = STFS_ExternalFileHandle::GetExternalFileHandle(pv_Fhandle);
    if (! lp_Efh) {
      errno = EBADF;
      TRACE_PRINTF2(1, "Error in obtaining External File Handle for %ld\n", pv_Fhandle);
      return -1;
    }
    
    lp_Efh->ResetErrors();

    /// Rev: Do we close . Set the state. Continue on errors. 

    // Closes the fragments
    int lv_Ret = lp_Efh->Close();
    if (lv_Ret < 0) {
      TRACE_PRINTF3(1, "Error %d while closing handle: %ld\n",
		   lv_Ret,
		   pv_Fhandle);
      // continue on error when closing
    }

    STFS_ExternalFileMetadata *lp_Efm = lp_Efh->EfmGet();
    if (!lp_Efm) {
      // corruption in some STFS maintained data structures. 
      STFS_util::SoftwareFailureHandler(WHERE);
      return -1;
    }

    lv_Ret = lp_Efm->Close(false);
    if (lv_Ret < 0) {
      TRACE_PRINTF3(1,"Error %d while closing handle: %ld\n",
		   lv_Ret,
		   pv_Fhandle);
      return -1;
    }

    lv_Ret = STFS_ExternalFileMetadata::DeleteFromContainer(lp_Efm);
    if (lv_Ret < 0) {
      STFS_util::SoftwareFailureHandler(WHERE);
      return lv_Ret;
    }

    // send message to the STFS daemon
#ifdef SQ_PACK
    lv_Ret = SendToSTFSd_close(&(lp_Efh->OpenIdentifierGet()),
                               STFS_util::GetMyNodeId(),
                               STFS_util::GetMyPID());
    if (lv_Ret < 0) {
      // 'errno' should be set here
      return lv_Ret;
    }
#else
    lv_Ret = STFSd_close(&(lp_Efh->OpenIdentifierGet()));
    if (lv_Ret < 0) {
      return lv_Ret;
    }
#endif

    // remove Efh from the Container
    lv_Ret = STFS_ExternalFileHandle::DeleteFromContainer(lp_Efh);
    if (lv_Ret < 0) {
      STFS_util::SoftwareFailureHandler(WHERE);
      return lv_Ret;
    }

    return 0;
  }