<?php
/************************************************************************/
/* mailserver.php                                                       */
/*----------------------------------------------------------------------*/
/* Defines DataComAccess class.                                         */
/*----------------------------------------------------------------------*/
/* Copyright (c) 2008-2009 Avaya Inc.                                   */
/************************************************************************/

require_once('user.php');
require_once('config.php');
require_once('common.php');
require_once('log.php');


class MediaEventSink {
 var $terminated = false;

 function MediaStateChanged($state) {
   GetEventLog()->WriteInfo("MediaStateChanged:".$state,0);
   GetMailserver()->SetMediaState($state);
 }
}

function GetMailserver()
{
  static $mailserver = null;
  if( !$mailserver )
  {
    $mailserver = new Mailserver();
    if( $mailserver->Init() == false )
    {
      $mailserver = null;
    }
  }
  return $mailserver;
}

class ComResult
{
  public $data = null;
  public $error = null;
  public $caller = null;
  function __construct( $caller, $result )
  {
    $this->data = null;
    $this->error = null;
    $this->caller = $caller;
    if( strncmp($result,"SUCCESS:",8) == 0 )
    {
      $this->data = substr($result, 8);
      if( $this->data == "FALSE" )
      {
        $this->data = 0;
      }
    }
    else if( strncmp($result,"FAILURE:",8) == 0 )
    {
      $this->error = substr($result, 8);
      GetEventLog()->WriteError('COM '.$caller.': ' . $this->error);
    }
  }
}

class Mailserver
{
  private $lastErr = '';
  private $vmpro = null;
  private $mediaState = 0;
  function __construct()
  {
  }

  public function Init()
  {
    try
    {
      $this->vmpro = new COM('vmprov5.WebVoicemail',null,CP_UTF8); // Format is dll_name.object_name
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError('Failed to initialise COM vmprov5.WebVoicemail. Exception: ' . $e->getMessage() );
      return false;
    }
    return ($this->vmpro != null)? true:false;
  }
  public function GetLastError()
  {
    return $this->lastErr;
  }

  public function SetMediaState( $state )
  {
    GetEventLog()->WriteInfo("SetMediaState:".$state,0);
    $this->mediaState = $state;
  }

  /**
   * *************************************************************************
   * Function: GetUserByName
   * Description: Finds user in the DB based on the submitted name, returns
   *        user object.
   *
   * @param string $name
   ****************************************************************************/
  public function GetUserByName( $name )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $name . ')';
    GetEventLog()->WriteInfo( $me );
    $user = null;
    if( !$name )
    {
      GetEventLog()->WriteError($me.' failed. Missing parameter.' );
    }
    else
    {
      try
      {
        if ( $this->vmpro != null)
        {
          $retval = $this->vmpro->GetUserByName($name);
          $result = new ComResult($me, $retval);
          $result->data = utf8_decode($result->data);
          if ($result->data != null && strlen($result->data)>0)
          {
            $user = new User();            
            $arr = explode('|', $result->data);
            $i=0;
            $user->id = UnescapeDelimiters($arr[$i++]);
            $user->name = UnescapeDelimiters($arr[$i++]);
            $user->extn = UnescapeDelimiters($arr[$i++]);
            $user->password = UnescapeDelimiters($arr[$i++]);
            $user->lockedOut = UnescapeDelimiters($arr[$i++]);
            $user->serviceLevel = UnescapeDelimiters($arr[$i++]);
            $user->pbxid = UnescapeDelimiters($arr[$i++]);
            $user->defaultFolderId = UnescapeDelimiters($arr[$i++]);
            $user->trashFolderId = UnescapeDelimiters($arr[$i++]);
            $user->invalidLoginCount = UnescapeDelimiters($arr[$i++]);
            $user->invalidLoginMax = UnescapeDelimiters($arr[$i++]);
            $user->type = UnescapeDelimiters($arr[$i++]);
            $user->online = UnescapeDelimiters($arr[$i++]);
            $user->canForwardToEmail = UnescapeDelimiters($arr[$i++]);
          }
        }
      }
      catch (Exception $e)
      {
        GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
        $user = null;
      }
    }
    return $user;
  }

  public function GetUserById( $sessionid,$userId )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $userId . ')';
    GetEventLog()->WriteInfo( $me );
    $user = null;
    if( $userId == "" )
    {
      GetEventLog()->WriteError($me.' failed. Missing parameter.' );
    }
    else
    {
      try
      {
        if ( $this->vmpro != null)
        {
          $result = new ComResult($me, $this->vmpro->GetUserById($sessionid,$userId));
          $result->data = utf8_decode($result->data);
          if ($result->data != null && strlen($result->data)>0)
          {
            $user = new User();
            $arr = explode('|', $result->data);
            $i=0;
            $user->id = UnescapeDelimiters($arr[$i++]);
            $user->name = UnescapeDelimiters($arr[$i++]);
            $user->extn = UnescapeDelimiters($arr[$i++]);
            $user->password = UnescapeDelimiters($arr[$i++]);
            $user->lockedOut = UnescapeDelimiters($arr[$i++]);
            $user->serviceLevel = UnescapeDelimiters($arr[$i++]);
            $user->pbxid = UnescapeDelimiters($arr[$i++]);
            $user->defaultFolderId = UnescapeDelimiters($arr[$i++]);
            $user->trashFolderId = UnescapeDelimiters($arr[$i++]);
            $user->invalidLoginCount = UnescapeDelimiters($arr[$i++]);
            $user->invalidLoginMax = UnescapeDelimiters($arr[$i++]);
            $user->type = UnescapeDelimiters($arr[$i++]);
            $user->online = UnescapeDelimiters($arr[$i++]);
            $user->canForwardToEmail = UnescapeDelimiters($arr[$i++]);            
          }
        }
      }
      catch (Exception $e)
      {
        GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
        $user = null;
      }
    }
    return $user;
  }


  public function GetLicencedUserCount()
  {
    $me = __CLASS__.'.'.__FUNCTION__.'()';
    GetEventLog()->WriteInfo( $me );
    $retval = -1;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->GetLicencedUserCount());
        if( $result->data != null )
        {
          $retval = $result->data;
        }
        else
        {
          $retval = 0;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
    }
    return $retval;
  }

  public function GetOnlineUserCount()
  {
    $me = __CLASS__.'.'.__FUNCTION__.'()';
    GetEventLog()->WriteInfo( $me );
    $retval = -1;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->GetOnlineUserCount());
        if( $result->data != null )
        {
          $retval = $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
    }
    return $retval;
  }


  public function GetMessages( $sessionid, $mailboxId, $folderId, $orderBy = null, $sortDir = null, $getAlways = true, $offset = 0, $amount = 0 )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionid.', '.$mailboxId . ', ' . $folderId . ', ' . $orderBy . ', ' . $sortDir . ', ' . $getAlways . ', ' . $offset . ', ' . $amount . ')';
    GetEventLog()->WriteInfo( $me );
    $retval = 'error';

    if( !$mailboxId || !$folderId )
    {
      GetEventLog()->WriteError($me.' failed. Missing parameter.' );
    }
    else
    {
      try
      {
        if ( $this->vmpro != null)
        {

          if ($orderBy == null)
            $orderBy = 0;
          if ($orderBy == 'date')
            $orderBy = 0;
          else if ($orderBy == 'from')
            $orderBy = 1;
          else if ($orderBy == 'to')
            $orderBy = 2;
          else if ($orderBy == 'length')
            $orderBy = 3;
          else if ($orderBy == 'state')
            $orderBy = 4;

          if ( $sortDir == null)
            $sortDir = 'DESC';

          $result = new ComResult($me, $this->vmpro->GetMessages( $sessionid, $mailboxId, $folderId, $orderBy, $sortDir, $getAlways, $offset, $amount ));
          if( $result->data != null )
          {
            $result->data = utf8_decode($result->data);
            $retval = $result->data;
          }

          /* the return string $retval is now in the following format
          totalNumMessages|numMessagesUnread;
          msgGuid|caller id|called id|calling party name|date|private|priority|state|length|media location;
          ...
          msgGuid|caller id|called id|calling party name|date|private|priority|state|length|media location;
          ***************************************************************************************************/
        }
      }
      catch (Exception $e)
      {
        GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      }
    }
    return $retval;
  }

  public function GetMailboxFolders($sessionid,$mailboxId)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $mailboxId . ')';
    GetEventLog()->WriteInfo( $me );
    if( !$mailboxId )
    {
      GetEventLog()->WriteError($me.' failed. Missing parameter.' );
      return '';
    }

    $retval = '';

    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->GetMailboxFolders($sessionid,$mailboxId));
        if( $result->data )
        {
          $retval = $result->data;
          // ID|Name|CanTranslate;
          // ...
          // ID|Name|CanTranslate;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
    }
    return $retval;
  }

  public function SetMessageState($sessionid,$mbId, $msgIds, $state)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $mbId . ', ' . $msgIds .  ', ' . $state . ')';
    GetEventLog()->WriteInfo( $me );
    $bSuccess = true;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->SetMessageState($sessionid,$mbId, $msgIds, $state));
        if( $result->data == null )
        {
          $bSuccess = false;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      $bSuccess = false;
    }
    return $bSuccess;
  }

  public function MoveMessages($sessionid,$mbId, $msgIds, $folderId)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $mbId . ', ' . $msgIds .  ', ' . $folderId . ')';
    GetEventLog()->WriteInfo( $me );
    $bSuccess = true;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->MoveMessages($sessionid,$mbId, $msgIds, $folderId));
        if( $result->data == null )
        {
          $bSuccess = false;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      $bSuccess = false;
    }
    return $bSuccess;
  }

  public function DeleteMessages($sessionid,$msgIds)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $msgIds . ')';
    GetEventLog()->WriteInfo( $me );
    $bSuccess = true;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->DeleteMessages($sessionid,$msgIds));
        if( $result->data == null )
        {
          $bSuccess = false;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      $bSuccess = false;
    }
    return $bSuccess;
  }

  public function IsUserAllowed( $sessionid,$userId )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionid . ', ' . $userId . ')';
    GetEventLog()->WriteInfo( $me );
    $allowed = false;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->IsUserAllowed( $sessionid,$userId ));
        if( $result->data != null )
        {
          $allowed = $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      return false;
    }
    return $allowed;
  }

  public  function LogoutUser( $sessionid,$userId )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $userId . ')';
    GetEventLog()->WriteInfo( $me );
    $bSuccess = true;
    try
    {
      if ( $this->vmpro != null )
      {
        $result = new ComResult($me, $this->vmpro->LogoutUser($sessionid,$userId));
        if( $result->data == null )
        {
          $bSuccess = false;
        }
      }
      return true;
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      $bSuccess = false;
    }
    return $bSuccess;
  }

  public function CreateNewFolder($sessionid,$mailboxID, $name)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $mailboxID . ', ' . $name . ')';
    GetEventLog()->WriteInfo( $me );
    $newId = -1;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->CreateNewFolder($sessionid,$mailboxID, $name));
        if( $result->data != null )
        {
          $newId = $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
    }
    return $newId;
  }

  public function SetUserPassword($sessionid,$mbId, $userId, $password, $oldpassword)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $mbId . ', ' . $userId . ', ' . $password . ', ' . $oldpassword . ')';
    GetEventLog()->WriteInfo( $me );
    $bSuccess = true;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->SetUserPassword($sessionid,$mbId, $userId, $password, $oldpassword));
        if( $result->data == null )
        {
          $bSuccess = false;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      $bSuccess = false;
    }
    return $bSuccess;
  }

  function GetLockedoutUsers($sessionid)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'()';
    GetEventLog()->WriteInfo( $me );
    $bSuccess = true;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->GetLockedUsers($sessionid));
        if( $result->data != null )
        {
          return $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      $bSuccess = false;
    }
    return $bSuccess;
  }

  function UnlockUsers($sessionid,$userIds)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $userIds . ')';
    GetEventLog()->WriteInfo( $me );
    $bSuccess = true;
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->UnlockUsers($sessionid,$userIds));
        if( $result->data != null )
        {
          return $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      $bSuccess = false;
    }
    return $bSuccess;
  }

  function GetMailboxes($sessionid, $userId, $type)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $userId . ', ' . $type . ')';
    GetEventLog()->WriteInfo( $me );
    $retval = '';
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->GetMailboxes($sessionid, $userId, $type));
        if( $result->data != null )
        {
          $result->data = utf8_decode($result->data);
          return $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
    }
    return $retval;
  }

  function Forward($sessionid,$mbId, $msgIds, $mbIds)
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $msgIds . ', ' . $mbIds . ')';
    GetEventLog()->WriteInfo( $me );
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->ForwardMessagesToMailboxes($sessionid,$mbId, $msgIds, $mbIds));
        if( $result->data == null )
        {
          return 'failure';
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      return 'Exception:' . $e->getMessage();
    }
    return 'success';
  }

  public function MediaCreate( $sessionId, $target )
  {
    $me = __CLASS__.'.'.__CLASS__.'.'.__FUNCTION__.'(' . $sessionId . ', ' .$target . ')';
    GetEventLog()->WriteInfo( $me );

    try
    {
      if( $this->vmpro != null)
      {
        $ret = $this->vmpro->MediaCreate( $sessionId, $target );
        $result = new ComResult($me, $ret);

        if( $result->error != null )
        {
          return 'failure';
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      return 'failure';
    }
    return 'success';
  }


  public function MediaMonitor( $sessionId )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionId . ')';
    GetEventLog()->WriteInfo( $me );

    $this->mediaState = "error";

    try
    {
      if( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->MediaMonitor( $sessionId ));
        if( $result->data == "attached ok" )
        {
          $this->mediaState = "timeout";
          $sink =& new MediaEventSink();  // TODO: Try using this
          com_event_sink($this->vmpro, $sink, "IWebVoicemailEvents");
          com_message_pump(12000);
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      $this->mediaState = "error";
    }

    return $this->mediaState;
  }


  public function MediaPlay( $sessionId, $srcExtn, $fileName )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionId . ', ' .$srcExtn . ', ' . $fileName . ')';
    GetEventLog()->WriteInfo( $me );
    try
    {
      if( $this->vmpro != null)
      {
        $ret = $this->vmpro->MediaPlay( $sessionId, $srcExtn, $fileName );
        $result = new ComResult($me, $ret);
        if( $result->data == null )
        {
          return false;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      return false;
    }
    return true;
  }


  private function CommandIdToDebugString( $commandId )
  {
    switch( $commandId )
    {
      case 1:
        return "play";
      case 2:
        return "stop";
      case 3:
        return "rwnd";
      case 4:
        return "ffwd";
      case 5:
        return "paus";
    }
    return $command_id;
  }

  public function MediaControl( $sessionId, $commandId )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionId . ', ' .$this->CommandIdToDebugString($commandId) . ')';
    GetEventLog()->WriteInfo( $me );
    try
    {
      if( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->MediaControl( $sessionId, $commandId ));
        if( $result->data == null )
        {
          return false;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      return false;
    }
    return true;
  }

  public function UpdateLastAction( $sessionid, $userId, $idletime )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionid . ',' . $userId . ',' . $idletime . ')';
    GetEventLog()->WriteInfo( $me );
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->UpdateLastAction( $sessionid, $userId, $idletime ));
        if( $result->data == null )
        {
          return false;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      return false;
    }
    return true;
  }


  public function UpdateLastContact( $sessionid, $userId, $idletime )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionid . ',' . $userId . ',' . $idletime . ')';
    GetEventLog()->WriteInfo( $me );
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->UpdateLastContact( $sessionid, $userId, $idletime ));
        if( $result->data == null )
        {
          return false;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      return false;
    }
    return true;
  }


  public function GetTimeSinceLastAction( $sessionid,$userId )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionid . ',' . $userId . ')';
    GetEventLog()->WriteInfo( $me );
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->GetTimeSinceLastAction( $sessionid,$userId ));
        if( $result->data != null )
        {
          return $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
    }
    return false;
  }

  public function GetTimeSinceLastContact( $sessionid,$userId )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $sessionid . ',' . $userId . ')';
    GetEventLog()->WriteInfo( $me );
    try
    {
      if ( $this->vmpro != null)
      {
        $result = new ComResult($me, $this->vmpro->GetTimeSinceLastContact( $sessionid,$userId ));
        if( $result->data != null )
        {
          return $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
    }
    return false;
  }
  
  public function AuditUserLogin( $userId, $successful )
  {
    $me = __CLASS__.'.'.__FUNCTION__.'(' . $userId . ')';
    GetEventLog()->WriteInfo( $me );
    try
    {
      if ( $this->vmpro != null)
      {
        $retval = $this->vmpro->AuditUserLogin( $userId, $successful );
        $result = new ComResult($me, $retval);
        if( $result->data != null )
        {
          $result->data = utf8_decode($result->data);
          return $result->data;
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
    }
    return false;
  }

  public function DialFromExtn( $sessionId, $target, $extn )
  {
    $me = __CLASS__.'.'.__CLASS__.'.'.__FUNCTION__.'(' . $sessionId . ', ' .$target . ', ' .$extn . ')';
    GetEventLog()->WriteInfo( $me );

    try
    {
      if( $this->vmpro != null)
      {
        $ret = $this->vmpro->DialFromExtn( $sessionId, $target, $extn );
        $result = new ComResult($me, $ret);

        if( $result->error != null )
        {
          return 'failure';
        }
      }
    }
    catch (Exception $e)
    {
      GetEventLog()->WriteError($me.' failed. Exception: '.$e->getMessage() );
      return 'failure';
    }
    return 'success';
  }
}

?>
