#Created by: Steven Manross
#email: steven@manross.net
#Create date: 9/13/2003

use Win32::OLE qw (in);
use Win32::OLE::Variant;
Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE);

my $TEXT_TO_SEARCH = "ThisTestThis";
my $ACTION_MOVE = 1;
my $CdoPR_TRANSPORT_MESSAGE_HEADERS = 0x7D001E;
my $profile = "SOMEEXCHANGESERVER"."\n"."Some user";

if (mapi_logon($mapi_session,$profile)) {
  if (create_rules_object($rules)) {
    if (create_spam_folder($mapi_session->GetInfoStore,$move_to_folder)) {
      my $inbox = $mapi_session->{Inbox};
      if (set_rule_folder ($rules,$inbox)) {
        print "Successfully set the folder for rule processing\n";
        if (create_condition($CdoPR_TRANSPORT_MESSAGE_HEADERS,$TEXT_TO_SEARCH,$objPropVal)) {
          print "Successfully created the processing condition\n";
          if (set_condition_options($objPropVal,$CdoPR_TRANSPORT_MESSAGE_HEADERS,0x10001,$objContCond)) {
            print "Successfully set the condition options\n";
            if (create_action($ACTION_MOVE,$move_to_folder,$Action)) {
              print "created action\n";
              if (create_rule("Move Test",$objContCond,$Action,$rule)) {
                print "Rule Created\n";
                if (add_rule_to_mailbox($rules,$rule)) {
                  print "Rule saved in mailbox\n";
                  if (mapi_logoff($mapi_session)) {
                    print "Success performing MAPI Logoff\n";
                  } else {
                    print "Failed MAPI Logoff.\n";
                  }
                } else {
                  print "failed saving rule in mailbox\n";
                }
              } else {
                print "Failed creating rule\n";
              }
            } else {
              print "Failed creating action\n";
            }
          } else {
            print "Failed setting condition options\n";    
          }
        } else {
          print "Failed creating search criteria\n";
        }
      } else {
        print "Failed setting rules folder..\n";
      }
    } else {
      print "Failed creating SPAM folder\n";
    }
  } else {
    print "Failed to create rules object\n";
  }
}
  
if (Win32::OLE->LastError() != 0) {
  print Win32::OLE->LastError();
}
exit;

sub mapi_logon {
  my $mapi_profile = $_[1];
  my $mapi_session = Win32::OLE->new("MAPI.Session");
  if (Win32::OLE->LastError() != 0) {
    print "Error creating MAPI object\n\n".Win32::OLE->LastError();
    return 0;
  }
  $mapi_session->Logon("","",0,1,0,0,$mapi_profile);
  if (Win32::OLE->LastError() != 0) {
    print "Error logging into mailbox\n".Win32::OLE->LastError();
    return 0;
  }
  $_[0] = $mapi_session;
  return 1;
}

sub create_rules_object {
  my $obj = Win32::OLE->new("MSExchange.Rules");
  if (Win32::OLE->LastError() != 0) {
    print "Error creaing Rules Collection\n\n".Win32::OLE->LastError();
    return 0;
  }
  $_[0] = $obj;
  return 1;
}

sub set_rule_folder {
  my $objrules = $_[0];
  my $objfolder = $_[1];
  $objrules->LetProperty('Folder', $objfolder);
  if (Win32::OLE->LastError() != 0) {
    print "Error \"Letting\" Folder property for rules object\n\n".Win32::OLE->LastError();
    return 0;
  }
  $objrules->Update();
  if (Win32::OLE->LastError() != 0) {
    print "Error \"Updating\" Folder property for rules object\n\n".Win32::OLE->LastError();
    return 0;
  }
  $_[0] = $objrules;
  return 1;
}

sub create_condition {
  my $tag = $_[0];
  my $value = $_[1];
  my $obj = Win32::OLE->new("MSExchange.PropertyValue");
  if (Win32::OLE->LastError() != 0) {
    print "Error creaing PropVal\n\n".Win32::OLE->LastError();
    return 0;
  }
  $obj->{Tag} = $tag;
  if (Win32::OLE->LastError() != 0) {
    print "Error setting Tag property for objPropVal\n\n".Win32::OLE->LastError();
    return 0;
  }
  $obj->{Value} = $value;
  if (Win32::OLE->LastError() != 0) {
    print "Error setting Value property for objPropVal\n\n".Win32::OLE->LastError();
    return 0;
  } else {
    $_[2] = $obj;
    return 1;
  }
}

sub set_condition_options {
  my $objPropVal = $_[0];
  my $tag = $_[1];
  my $options = $_[2];
  # Create ContentCondition
  my $objContCond = Win32::OLE->new("MSExchange.ContentCondition");
  if (Win32::OLE->LastError() != 0) {
    print "Error creaing ContentCondition\n\n".Win32::OLE->LastError();
    return 0;
  }
  $objContCond->LetProperty('Value',$objPropVal);
  if (Win32::OLE->LastError() != 0) {
    print "Error setting Value property for ObjContCond\n\n".Win32::OLE->LastError();
    return 0;
  }
  $objContCond->{PropertyType} = $tag;
  if (Win32::OLE->LastError() != 0) {
    print "Error setting PropertyType property for ObjContCond\n\n".Win32::OLE->LastError();
    return 0;
  }
  print "options = ".$options."\n";
  $objContCond->{Operator} = $options;
  if (Win32::OLE->LastError() != 0) {
    print "Error setting Operator property for ObjContCond\n\n".Win32::OLE->LastError();
    return 0;
  } else {
    $_[3] = $objContCond;
    return 1;
  }
}

sub create_action {
  my $actiontype = $_[0];
  my $arg = $_[1];
  my $obj = Win32::OLE->new("MSExchange.Action");
  if (Win32::OLE->LastError() != 0) {
    die "Error Creating new action\n\n".Win32::OLE->LastError();
  }
  
  $obj->{'ActionType'} = $actiontype;
  if (Win32::OLE->LastError() != 0) {
    die "Error \"Put\"ting ActionType property for Action\n\n".Win32::OLE->LastError();
  }
  if (!($actiontype =~ /^(3|8|10|11)$/)) { #3 == delete, 8 == Bounce, 10 == MarkRead, 11 == Defer
    $obj->LetProperty('Arg',$arg);
    if (Win32::OLE->LastError() != 0) {
      print "Error \"Put\"ting Arg property for Action\n\n".Win32::OLE->LastError();
      return 0;
    }
  }
  $_[2] = $obj;
  return 1;
}

sub create_rule {
  my $name = $_[0];
  my $condition = $_[1];
  my $objaction = $_[2];
  my $obj = Win32::OLE->new("MSExchange.Rule");
  if (Win32::OLE->LastError() != 0) {
    print "Error Creating Rule object\n\n".Win32::OLE->LastError();
    return 0;
  }
  
  $obj->{Name} = $name;
  if (Win32::OLE->LastError() != 0) {
    print "Error setting Name property for Rule\n\n".Win32::OLE->LastError();
    return 0;
  }
  $obj->LetProperty('Condition',$condition);
  if (Win32::OLE->LastError() != 0) {
    print "Error setting Condition property for Rule\n\n".Win32::OLE->LastError();
    return 0;
  }
  $obj->{Actions}->Add(Variant(VT_I4,($obj->{Actions}->Count+1)),$objaction);
  if (Win32::OLE->LastError() != 0) {
    print "Error adding action for Rule\n\n".Win32::OLE->LastError();
    return 0;
  }
  $_[3] = $obj;
  return 1;
}

sub add_rule_to_mailbox {
  my $obj = $_[0];
  my $rule = $_[1];
  $obj->Add(Variant(VT_I4,($obj->{Count} + 1)),$rule);
  if (Win32::OLE->LastError() != 0) {
    print "Error rule to Rules Collection\n\n".Win32::OLE->LastError();
    return 0;
  }
  
  $obj->Update();
  if (Win32::OLE->LastError() != 0 ) {
    print "error in update\n".Win32::OLE->LastError()."\n";
    return 0;
  }
  $obj->UpdateIndices();
  if (Win32::OLE->LastError() != 0) {
    print "Error updating the Rules Collection\n\n".Win32::OLE->LastError();
    return 0;
  }
  $_[0] = $obj;
  return 1;
}

sub mapi_logoff {
  my $mapi_session = $_[0];
  $mapi_session->Logoff();
  if (Win32::OLE->LastError() != 0) {
    print "Error logging off of mailbox\n".Win32::OLE->LastError();
    return 0;
  } else {
    return 1;
  }
}

sub get_correct_folder {
  my $info_store = $_[0];
  my $folder_name = $_[1];
  foreach my $folder (in ($info_store->RootFolder->Folders)) {
    if (uc($folder->{Name}) eq $folder_name) {
      print "Found correct folder: $folder->{Name}\n";
      return 1;
    }
  }
  return 0;
}

sub create_spam_folder {
  my $info_store = $_[0];
  my $folder_name = "SPAM";
  if (get_correct_folder($info_store,$folder_name)) {
    return 0;
  } else {
    my $folder = $info_store->RootFolder->Folders()->Add($folder_name);
    $_[1] = $folder;
    return 1;
  }
}