/*
 * Account manager implementation.
 */

#include "AccountManagerImpl.h"

AccountManagerImpl::AccountManagerImpl (Util &util)
  : POA_Bank::AccountManager ()
  , util_ (util)
{
}

void
AccountManagerImpl::createAccount (const char *name, CORBA::Float amount)
{
  try
    {
      Bank::Account_var accountVar = getAccount (name);
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("The account with name %s already exists\n"),
                  name));

      throw Bank::AccountManager::AlreadyExists ();
    }
  catch (const Bank::AccountManager::NotFound &)
    {
      // No action needed.
    }

  // Create the implementation for the new account.
  AccountImpl *pNewAccount = 0;
  ACE_NEW_THROW_EX (pNewAccount,
                    AccountImpl (name, amount),
                    CORBA::NO_MEMORY ());
  PortableServer::ServantBase_var holder (pNewAccount);
  servants_.push_back (holder);

  // Create the CORBA object for the new account.
  PortableServer::POA_var rootPoaVar = _default_POA ();
  PortableServer::POAManager_var rootManagerVar =
    rootPoaVar->the_POAManager ();
  rootManagerVar->activate ();

  PortableServer::ObjectId_var oid =
    rootPoaVar->activate_object (pNewAccount);
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Activated account servant\n")));

  // Add the account to the naming service.
  CORBA::Object_var objVar = pNewAccount->_this ();
  util_.addAccount (name, objVar.in ());

  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Successfully created account with the following details:\n")));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Account Holder's name: %s\n"), name));
}

Bank::Account_ptr
AccountManagerImpl::getAccount (const char *name)
{
  Bank::Account_var accountVar = util_.getAccount (name);

  if (CORBA::is_nil (accountVar.in ()))
    {
      throw Bank::AccountManager::NotFound ();
    }
  else
    {
      return Bank::Account::_duplicate (accountVar.in ());
    }
}
