AmSession* AnswerMachineFactory::onInvite(const AmSipRequest& req)
{
  string language;
  string email;
  string domain;
  string user;
  string sender;
  string typ;

  int vm_mode = MODE_VOICEMAIL; 

  string iptel_app_param = getHeader(req.hdrs, PARAM_HDR);

  if (!iptel_app_param.length()) {
    throw AmSession::Exception(500, "voicemail: parameters not found");
  }

  language = get_header_keyvalue(iptel_app_param, "lng", "Language");
  email = get_header_keyvalue(iptel_app_param, "eml", "Email-Address");

  string mode = get_header_keyvalue(iptel_app_param,"mod", "Mode");
  if (!mode.empty()) {
    if (mode == "box")
      vm_mode = MODE_BOX;
    else if (mode == "both")
      vm_mode = MODE_BOTH;
    else if (mode == "ann")
      vm_mode = MODE_ANN;
  }

  if (((vm_mode == MODE_BOTH) || (vm_mode == MODE_VOICEMAIL)) &&
      (email.find('@') == string::npos)) {
    ERROR("no @ found in email address '%s' from params '%s'\n",
	  email.c_str(), iptel_app_param.c_str());
    throw AmSession::Exception(500, "voicemail: no email address");
  }

  user = get_header_keyvalue(iptel_app_param,"usr", "User");
  if (!user.length())
    user = req.user;
  
  sender = get_header_keyvalue(iptel_app_param, "snd", "Sender");
  if (!sender.length()) 
    sender = req.from;  
  
  domain = get_header_keyvalue(iptel_app_param, "dom", "Domain");
  if (!domain.length())
    domain = req.domain;

  typ = get_header_keyvalue(iptel_app_param, "typ", "Type");
  if (!typ.length())
    typ = DEFAULT_TYPE;

  // checks
  if (user.empty()) 
    throw AmSession::Exception(500, "voicemail: user missing");

  if (sender.empty()) 
    throw AmSession::Exception(500, "voicemail: sender missing");

  if (((vm_mode == MODE_BOX) || (vm_mode == MODE_BOTH))
      && (NULL == MessageStorage)) {
    throw AmSession::Exception(500, "voicemail: no message storage available");
  }
    

  DBG("voicemail invocation parameters: \n");
  DBG(" Mode:     <%s> \n", mode.c_str());
  DBG(" Email:    <%s> \n", email.c_str());
  DBG(" User:     <%s> \n", user.c_str());
  DBG(" Sender:   <%s> \n", sender.c_str());
  DBG(" Domain:   <%s> \n", domain.c_str());
  DBG(" Language: <%s> \n", language.c_str());
  DBG(" Type:     <%s> \n", typ.c_str());

  FILE* greeting_fp = NULL;
  if (TryPersonalGreeting)
    greeting_fp = getMsgStoreGreeting(typ, user, domain);

#ifdef USE_MYSQL

  string announce_file;

  if (get_audio_file(GREETING_MSG, domain, req.user, "",
                    &announce_file) && !announce_file.empty())
    goto announce_found;

  if (!language.empty()) {
    if (get_audio_file(GREETING_MSG, domain, "", language,
                      &announce_file) && !announce_file.empty())
      goto announce_found;
  } else {
    if (get_audio_file(GREETING_MSG, domain, "", "",
                      &announce_file) && !announce_file.empty())
      goto announce_found;
  }

  if (!language.empty())
    if (get_audio_file(GREETING_MSG, "", "", language,
                      &announce_file) && !announce_file.empty())
      goto announce_found;

  get_audio_file(GREETING_MSG, "", "", "", &announce_file);

#else

  string announce_file = add2path(AnnouncePath,2, 
				  domain.c_str(), (user + ".wav").c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,3, 
			     domain.c_str(), language.c_str(), DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }

  announce_file = add2path(AnnouncePath,2, 
			   domain.c_str(), DefaultAnnounce.c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,2, 
			     language.c_str(),  DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }
	
  announce_file = add2path(AnnouncePath,1, DefaultAnnounce.c_str());
  if (!file_exists(announce_file)) 
    announce_file = "";

#endif

 announce_found:
  if(announce_file.empty())
    throw AmSession::Exception(500,"voicemail: no greeting file found");

  // VBOX mode does not need email template
  if ((vm_mode == MODE_BOX) || (vm_mode == MODE_ANN))
    return new AnswerMachineDialog(user, sender, domain,
				   email, announce_file, greeting_fp,
				   vm_mode, NULL);
				    
  if(email.empty())
    throw AmSession::Exception(404,"missing email address");

  map<string,EmailTemplate>::iterator tmpl_it;
  if (!language.empty()) {
    tmpl_it = email_tmpl.find(domain + "_" + language);
    if(tmpl_it == email_tmpl.end()) {
      tmpl_it = email_tmpl.find(domain);
      if(tmpl_it == email_tmpl.end()) {
	tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL + "_"
				  + language);
	if(tmpl_it == email_tmpl.end())
	  tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
      }
    }
  } else {
    tmpl_it = email_tmpl.find(domain);
    if(tmpl_it == email_tmpl.end())
      tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
  }
    
  if(tmpl_it == email_tmpl.end()){
    ERROR("Voicemail: unable to find an email template.\n");
    return 0;
  }
  return new AnswerMachineDialog(user, sender, domain,
				 email, announce_file, greeting_fp,
				 vm_mode, &tmpl_it->second);
}
AmSession* AnswerMachineFactory::onInvite(const AmSipRequest& req, const string& app_name,
					  const map<string,string>& app_params)
{
  string language;
  string email;
  string domain;
  string user;
  string sender;
  string typ;
  string uid; // user ID
  string did; // domain ID
  string mode;
  string iptel_app_param;

  EmailTmplDict template_variables;

  int vm_mode = DefaultVMMode; 

  if(SimpleMode) {
    email = EmailAddress;
    uid = user = req.user;
    //did = domain = req.domain;
    did = domain = "default";
    sender = req.from;
    typ = DEFAULT_TYPE;
  }
  else {
  
    iptel_app_param = getHeader(req.hdrs, PARAM_HDR, true);
    mode = get_header_keyvalue(iptel_app_param,"mod", "Mode");
    
    if (!EmailAddress.length()) {
      
      if (!iptel_app_param.length()) {
	throw AmSession::Exception(500, "voicemail: parameters not found");
      }
      
      language = get_header_keyvalue(iptel_app_param, "lng", "Language");
      email = get_header_keyvalue(iptel_app_param, "eml", "Email-Address");
      
      if (!mode.empty()) {
	if (mode == "box")
	  vm_mode = MODE_BOX;
	else if (mode == "both")
	  vm_mode = MODE_BOTH;
	else if (mode == "ann")
	  vm_mode = MODE_ANN;
      }
    } else {
      // overrides email address
      //vm_mode = MODE_VOICEMAIL;
      email = EmailAddress;
    }
    
    if (((vm_mode == MODE_BOTH) || (vm_mode == MODE_VOICEMAIL)) &&
	(email.find('@') == string::npos)) {
      ERROR("no @ found in email address '%s' from params '%s'\n",
	    email.c_str(), iptel_app_param.c_str());
      throw AmSession::Exception(500, "voicemail: no email address");
    }
    
    user = get_header_keyvalue(iptel_app_param,"usr", "User");
    if (!user.length())
      user = req.user;
    
    sender = get_header_keyvalue(iptel_app_param, "snd", "Sender");
    if (!sender.length()) 
      sender = req.from;  
    
    domain = get_header_keyvalue(iptel_app_param, "dom", "Domain");
    if (!domain.length())
      domain = req.domain;
    
    typ = get_header_keyvalue(iptel_app_param, "typ", "Type");
    if (!typ.length())
      typ = DEFAULT_TYPE;
    
    uid = get_header_keyvalue(iptel_app_param, "uid", "UserID");
    if (uid.empty())
      uid=user;
    
    did = get_header_keyvalue(iptel_app_param, "did", "DomainID");
    if (did.empty())
      did=domain;
  }
    
  // checks
  if (uid.empty()) 
    throw AmSession::Exception(500, "voicemail: user missing");
  
  if (sender.empty()) 
    throw AmSession::Exception(500, "voicemail: sender missing");
  
  if (((vm_mode == MODE_BOX) || (vm_mode == MODE_BOTH))
      && (NULL == MessageStorage)) {
    throw AmSession::Exception(500, "voicemail: no message storage available");
  }
  
  
  DBG("voicemail invocation parameters: \n");
  DBG(" Mode:     <%s> \n", mode.c_str());
  DBG(" Email:    <%s> \n", email.c_str());
  DBG(" User:     <%s> \n", user.c_str());
  DBG(" Sender:   <%s> \n", sender.c_str());
  DBG(" Domain:   <%s> \n", domain.c_str());
  DBG(" Language: <%s> \n", language.c_str());
  DBG(" Type:     <%s> \n", typ.c_str());
  DBG(" UID:      <%s> \n", uid.c_str());
  DBG(" DID:      <%s> \n", did.c_str());
  
  FILE* greeting_fp = NULL;
  if (TryPersonalGreeting)
    greeting_fp = getMsgStoreGreeting(typ, uid, did);

#ifdef USE_MYSQL

  string announce_file;

  if (get_audio_file(GREETING_MSG, domain, req.user, "",
                    announce_file) && !announce_file.empty())
    goto announce_found;

  if (!language.empty()) {
    if (get_audio_file(GREETING_MSG, domain, "", language,
                      announce_file) && !announce_file.empty())
      goto announce_found;
  } else {
    if (get_audio_file(GREETING_MSG, domain, "", "",
                      announce_file) && !announce_file.empty())
      goto announce_found;
  }

  if (!language.empty())
    if (get_audio_file(GREETING_MSG, "", "", language,
                      announce_file) && !announce_file.empty())
      goto announce_found;

  get_audio_file(GREETING_MSG, "", "", "", announce_file);

#else

  string announce_file = add2path(AnnouncePath,2, 
				  did.c_str(), (uid + ".wav").c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,3, 
			     did.c_str(), language.c_str(), DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }

  announce_file = add2path(AnnouncePath,2, 
			   did.c_str(), DefaultAnnounce.c_str());
  if (file_exists(announce_file)) goto announce_found;

  if (!language.empty()) {
    announce_file = add2path(AnnouncePath,2, 
			     language.c_str(),  DefaultAnnounce.c_str());
    if (file_exists(announce_file)) goto announce_found;
  }
	
  announce_file = add2path(AnnouncePath,1, DefaultAnnounce.c_str());
  if (!file_exists(announce_file)) 
    announce_file = "";

#endif

 announce_found:
  if(announce_file.empty())
    throw AmSession::Exception(500,"voicemail: no greeting file found");

  if(!SimpleMode) {

    // a little inefficient this way - but get_header_keyvalue supports escaping
    for (vector<string>::iterator it=
	   MailHeaderVariables.begin(); it != MailHeaderVariables.end(); it++) {
      template_variables[*it] = get_header_keyvalue(iptel_app_param, *it);
    }
  }

  // VBOX mode does not need email template
  if ((vm_mode == MODE_BOX) || (vm_mode == MODE_ANN))
    return new AnswerMachineDialog(user, sender, domain,
				   email, announce_file, uid, did, 
				   greeting_fp, vm_mode, 
				   template_variables, NULL);

  if(email.empty())
    throw AmSession::Exception(404,"missing email address");

  map<string,EmailTemplate>::iterator tmpl_it;
  if (!language.empty()) {
    tmpl_it = email_tmpl.find(did + "_" + language);
    if(tmpl_it == email_tmpl.end()) {
      tmpl_it = email_tmpl.find(did);
      if(tmpl_it == email_tmpl.end()) {
	tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL + "_"
				  + language);
	if(tmpl_it == email_tmpl.end())
	  tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
      }
    }
  } else {
    tmpl_it = email_tmpl.find(did);
    if(tmpl_it == email_tmpl.end())
      tmpl_it = email_tmpl.find(DEFAULT_MAIL_TMPL);
  }
    
  if(tmpl_it == email_tmpl.end()){
    ERROR("Voicemail: unable to find an email template.\n");
    return 0;
  }
  return new AnswerMachineDialog(user, sender, domain,
				 email, announce_file, 
				 uid, did,
				 greeting_fp,
				 vm_mode, template_variables,
				 &tmpl_it->second);
}