package Distribution;

use strict;
use warnings;

use LWP;
use Digest::MD5 qw(md5 md5_hex md5_base64);

use lib qw(Core);
use lib qw(Classes);

use Configuration;
use LocalConfiguration;

use Email;
use Logger;
use String;
use PDBUtils;

use TargetsManager;
use GroupsManager;
use JobsManager;

my $RESPONSE_TIMEOUT = 30; # in sec

### METHODS (last update 05/24/2010 M. Wojciechowski):
#   submit (sending requests with targets to the registered servers)
#   process_email_request (sends request to the email server)
#   process_http_request (sends request to the http server depending)
#   build_request_url (setting up the request url for GET)
#   build_post_request (setting up the request url for POST)
#   build_email_request (creates email to be sent to the email server)
#   format_sequence (validates sequence type and formats if needed)
#   save_request (saves request)
#   save_response (saves response)
#   save_file (saves file)
#   log (adds string to the log)
#   receive_response (returns group of server that had sent email to us
#                     and saves information about it)

sub new {
    my ($class, $debug) = @_;
    
    my $self = {
        _database => Database->new($CONFIG->{HOSTNAME}, $CONFIG->{PORT}, $CONFIG->{DATABASE}, $CONFIG->{USERNAME}, $CONFIG->{PASSWORD}),
        _logger => Logger->new()
    };
    
    # by default debug mode is turned on
    $self->{_debug} = !defined($debug) ? 1 : $debug;
    
    $self->{_logger}->set_info_log('distribution.log');
    
    bless $self, $class;
    return $self;
}

sub submit {
    (@_ == 4) || die("Invalid arguments supplied");
    my ($self, $target_id, $group_id, $is_qa_request) = @_;
    
    my $uid = md5_hex(sprintf("casp13%s%d%d%d", join(':', localtime()), $target_id, $group_id, rand(9999))); # generate unique uid for response and request
    
    my $result = 0;
    
    $target_id = int($target_id);
    $group_id = int($group_id);
    
    $self->log($uid, "START PROCESSING");
    $self->log($uid, sprintf("Input Parameters: Target: %d, Group: %d, Request type: %s", $target_id, $group_id, ($is_qa_request) ? "QA" : "Regular"));
    
    my $targets_manager = new TargetsManager();
    
    if(!$targets_manager->exist($target_id)) {
        $self->log($uid, "ERROR! Target doesn't exist!");
        $self->log($uid, "PROCESSING FAILED!");
        return $result;
    } elsif(!$targets_manager->is_published($target_id)) {
        $self->log($uid, "ERROR! Target wasn't published yet!");
        $self->log($uid, "PROCESSING FAILED!");
        return $result;
    }
    
    my $groups_manager = new GroupsManager();
    
    my %server_info = $groups_manager->info_server($group_id);
    
    if(!$groups_manager->exist($group_id)) {
        $self->log($uid, "ERROR! Group doesn't exist!");
        $self->log($uid, "PROCESSING FAILED!");
        return $result;
    }
    
    my $group_name = $groups_manager->name($group_id);
    my $target_name = $targets_manager->name($target_id);
    $self->log($uid, sprintf("Info: %s, %s", $group_name, $target_name));
    
    my $type = $server_info{TYPE};
    
    my $is_email_server = 0;
    if($type == 0) {
        $self->log($uid, sprintf("ERROR! %s:%s Group isn't server!",$target_name, $group_name));
        $self->log($uid, "PROCESSING FAILED!");
        return $result;
    } elsif($type == 1) {
        $is_email_server = 0;
        $self->log($uid, "Group is Regular Server");
    } elsif($type == 2) {
        $is_email_server = 1;
        $self->log($uid, "Group is Email Server");
    } else {
        $self->log($uid, sprintf("ERROR! %s:%s Invalid group type!",$target_name, $group_name));
        $self->log($uid, "PROCESSING FAILED!");
        return $result;
    }
    
    my $is_blocked = $groups_manager->is_blocked($group_id);
    if($is_blocked) {
        $self->log($uid, sprintf("ERROR! %s:%s Group is blocked by administrator!",$target_name, $group_name));
        $self->log($uid, "PROCESSING FAILED!");
        return $result;
    }
    
    my $jobs_manager = new JobsManager();
    
    my $job_id = $jobs_manager->register($target_id, $group_id, $uid);
    if($job_id <= 0) {
        $self->log($uid, sprintf("ERROR! %s:%s Job registration FAILED!",$target_name, $group_name));
        $self->log($uid, "PROCESSING FAILED!");
        return $result;
    }
    
    $self->log($uid, sprintf("Job was successfully registered, ID: %d", $job_id));
    
    my $request_method = $server_info{REQUEST_METHOD};
    
    if(!$self->{_debug}) {
        my $request_send_status = 0;
        if(!$is_email_server) {
            $request_send_status = $self->process_http_request($target_id, $group_id, $job_id, $uid, $request_method, $is_qa_request,$target_name, $group_name);
        } else {
            $request_send_status = $self->process_email_request($target_id, $group_id, $job_id, $uid, $is_qa_request,$target_name, $group_name);
        }
        
        if(! $request_send_status) {
            $self->log($uid, sprintf("ERROR! %s:%s Processing request FAILED!", $target_name, $group_name));
            $self->log($uid, "PROCESSING FAILED!");
            return $result;
        }
    }
    
    $self->log($uid, "END PROCESSING");
    $result = 1;
    
    return $result;
}

sub process_email_request {
    (@_ == 8) || die("Invalid arguments supplied");
    my ($self, $targets_id, $groups_id, $job_id, $uid, $is_qa_request,$target_name, $group_name) = @_;
    
    my $result = 0;
    
    $self->log($uid, "Email request initialized");
    
    my $body = $self->build_email_request($targets_id, $groups_id, $uid, $is_qa_request);
    
    if($body eq '') {
        $self->log($uid, sprintf("ERROR! %s:%s  Request wasn't generated!",$target_name, $group_name));
        return $result;
    }
    
    my $targets_manager = new TargetsManager();
    my %target_info = $targets_manager->info($targets_id);
    
    my $request_text = sprintf("Subject: %s\n\n", $target_info{NAME});
    $request_text = sprintf("%sBody:\n%s\n", $request_text, $body);
    
    my $groups_manager = new GroupsManager();
    my %server_info = $groups_manager->info_server($groups_id);
    
    my $email = $server_info{REQUEST_EMAIL};
    
    if(trim($email) eq '') {
        $self->log($uid, sprintf("ERROR! %s:%s Invalid recepient email!",$target_name, $group_name));
        return $result;
    }
    
    Email::send_email($LOCAL_CONFIG->{SERVERS_REQUEST_META_EMAIL}, $email, $LOCAL_CONFIG->{SERVERS_REQUEST_META_EMAIL}, "", $target_info{NAME}, $body);
    
    my $jobs_manager = new JobsManager();
    
    # add request into database
    if($jobs_manager->request($job_id) != 1) {
        $self->log($uid, sprintf("ERROR! %s:%s  Request wasn't saved to database!",$target_name, $group_name));
        return $result;
    }
    
    # save request into uid.request file into request directory
    if($self->save_request($uid, $request_text) != 1) {
        $self->log($uid, sprintf("ERROR! %s:%s  Request file wasn't saved!",$target_name, $group_name));
        return $result;
    }
    
    $self->log($uid, sprintf("%s:%s Email has been sent",$target_name, $group_name));
    
    my @log_request = split(/\n/, $request_text);
    
    for(my $i = 0; $i < scalar(@log_request); $i++) { 
        $self->log($uid, $log_request[$i]);
    }
    
    # till this point everything looks OK
    $result = 1;
    
    return $result;
}

sub process_http_request {
    (@_ == 9) || die("Invalid arguments supplied");
    my ($self, $targets_id, $groups_id, $job_id, $uid, $request_method, $is_qa_request,$target_name, $group_name) = @_;
    
    my $result = 0;
    
    my $agent = LWP::UserAgent->new();
    $agent->timeout($RESPONSE_TIMEOUT);
    
    my $request_text = '';
    my $response;
    
    $self->log($uid, sprintf("%s:%s HTTP request initialized",$target_name, $group_name));
    
    if(lc($request_method) eq 'get') {
        my $request_url = $self->build_request_url($targets_id, $groups_id, $uid, $is_qa_request);
        my $request = HTTP::Request->new(GET => $request_url);
        if($request_url eq '') {
            $self->log($uid, sprintf("ERROR! %s:%s  Request url wasn't built!",$target_name, $group_name));
            return $result;
        }
        
        $self->log($uid, sprintf("URL: %s", $request_url));
        
        $response = $agent->request($request);
        
        $request_text = sprintf("GET REQUEST\n");
        $request_text = sprintf("%s%s", $request_text, $request_url);
    } elsif(lc($request_method) eq 'post') {
        my @post_request = $self->build_post_request($targets_id, $groups_id, $uid, $is_qa_request);
        
        if(scalar(@post_request) == 0) {
            $self->log($uid, sprintf("ERROR! %s:%s  Request post parameters string are not defined!",$target_name, $group_name));
            return $result;
        }
       
	# check if server is https
        if ($post_request[0] =~ m/^https/) {
               # @post_request = $self->redirect_post_request_for_https(\@post_request);
        }
 
        $self->log($uid, sprintf("%s:%s URL: %s", $target_name, $group_name, $post_request[0]));
        
        my @parameters = @{$post_request[1]};
        
        $request_text = sprintf("POST REQUEST\n");
        $request_text = sprintf("%s%s\n", $request_text, $post_request[0]);
        
        for(my $i = 0; $i < scalar(@parameters); $i++) {
            my $request_string = sprintf("%s=>%s", $parameters[$i], $parameters[$i + 1]);
            $self->log($uid, sprintf("\t%s", $request_string));
            $request_text = sprintf("%s%s\n", $request_text, $request_string);
            $i++;
        }
        
        $response = $agent->post(@post_request);
    } else {
        $self->log($uid,sprintf("ERROR! %s:%s Invalid request method! Should be 'get' or 'post'",$target_name, $group_name));
        return $result;
    }
    
    my $jobs_manager = new JobsManager();
    
    # add request into database
    if($jobs_manager->request($job_id) != 1) {
        $self->log($uid, sprintf("ERROR! %s:%s Request wasn't saved to database!",$target_name, $group_name));
        return $result;
    }
    
    # save request into uid.request file into request directory
    if($self->save_request($uid, $request_text) != 1) {
        $self->log($uid, sprintf("ERROR! %s:%s Request file wasn't saved!",$target_name, $group_name));
        return $result;
    }
    
    $self->log($uid, sprintf("%s:%s Request has been sent", $target_name, $group_name));
    
    if(!$response->is_success) {
        $self->log($uid, sprintf("ERROR! %s:%s Response wasn't success!",$target_name, $group_name));
        $self->log($uid, sprintf("ERROR! %s:%s Status line: %s", $target_name, $group_name, $response->status_line));
        return $result;
    }
    
    my $response_text = $response->content;
    
    # add response into database
    if($jobs_manager->response($job_id, $response_text) != 1) {
        $self->log($uid, sprintf("ERROR! %s:%s Response wasn't saved to database!",$target_name, $group_name));
        return $result;
    }
    
    # save response into uid.response file into response directory
    if($self->save_response($uid, $response_text) != 1) {
        $self->log($uid, sprintf("ERROR! %s:%s Response file wasn't saved!",$target_name, $group_name));
        return $result;
    }
    
    # till this point everything looks OK
    $result = 1;
    
    return $result;
}

sub build_request_url {
    (@_ == 5) || die("Invalid arguments supplied");
    my ($self, $targets_id, $groups_id, $uid, $is_qa_request) = @_;
    
    my $result = '';
    
    my $targets_manager = new TargetsManager();
    my $groups_manager = new GroupsManager();
    
    my %target_info = $targets_manager->info($targets_id);
    my %server_info = $groups_manager->info_server($groups_id);
    
    my $url = String::trim($server_info{REQUEST_CGI});
    
    if($url eq '') {
        $self->log($uid, "ERROR! REQUEST_CGI is empty");
        return $result;
    } elsif(($url =~ /\?/) || ($url =~ /\&/) || ($url =~ / /)) {
        $self->log($uid, sprintf("WARNING! REQUEST_CGI contains invalid characters! It may cause problems. Group: %s. URL: %s", $server_info{NAME}, $server_info{REQUEST_CGI}));
    }
    
    $url = sprintf("%s?", $url);
    $url = sprintf("%s%s=%s&", $url, $server_info{TARGET_NAME_KEY}, $target_info{NAME});   # target name
    $url = sprintf("%s%s=%s&", $url, $server_info{SEQUENCE_KEY}, $self->format_sequence($target_info{NAME}, $target_info{SEQUENCE}, $server_info{SEQUENCE_FORMAT},$target_info{SUBUNIT}));   # sequence name
    $url = sprintf("%s%s=%s&", $url, $server_info{EMAIL_KEY}, $LOCAL_CONFIG->{SERVERS_DISTRIBUTION_EMAIL});   # email
    if (defined($server_info{STOICHIOMETRY_KEY}) && String::trim($server_info{STOICHIOMETRY_KEY}) ne ''){ 
      $url = sprintf("%s%s=%s&", $url, $server_info{STOICHIOMETRY_KEY}, $target_info{STOICHIOMETRY});   # stoichiometry
    }
    
    if($is_qa_request && $groups_manager->is_qa_server($groups_id)) {
        $url = sprintf("%s%s=%s/%s.stage%1d.3D.srv.tar.gz&", $url, $server_info{TARBALL_KEY}, $LOCAL_CONFIG->{QA_TARBALL_LOCATION}, $targets_manager->name($targets_id),$is_qa_request);   # tarball
    }

    # add additional parameter - location of the file for assissted targets
    if ($target_info{NAME} =~ m/^[SNFAXL]/){
	if (defined($server_info{ADDFILE_KEY}) && String::trim($server_info{ADDFILE_KEY}) ne ''){
		$url = sprintf("%s%s=%s/%s.tar.gz&", $url, $server_info{ADDFILE_KEY}, $LOCAL_CONFIG->{EXTRA_EXP_TARBALL_LOCATION}, $target_info{NAME});
	}
    } elsif ($target_info{NAME} =~ m/^R/){
        if (defined($server_info{ADDFILE_KEY}) && String::trim($server_info{ADDFILE_KEY}) ne ''){
		$url = sprintf("%s%s=%s/%s.pdb.txt&", $url, $server_info{ADDFILE_KEY}, $LOCAL_CONFIG->{EXTRA_EXP_TARBALL_LOCATION}, $target_info{NAME});
        }
    }


    if(String::trim($server_info{OTHER}) ne '') {
        $url = sprintf("%s%s", $url, $server_info{OTHER});   # other parameters
    }
    
    $result = $url;
    
    return $result;
}

sub build_post_request {
    (@_ == 5) || die("Invalid arguments supplied");
    my ($self, $targets_id, $groups_id, $uid, $is_qa_request) = @_;
    
    my @result = ();
    
    my $targets_manager = new TargetsManager();
    my $groups_manager = new GroupsManager();
    
    my %target_info = $targets_manager->info($targets_id);
    my %server_info = $groups_manager->info_server($groups_id);
    
    my $url = String::trim($server_info{REQUEST_CGI});
    
    if($url eq '') {
        $self->log($uid, "ERROR! REQUEST_CGI is empty");
        return @result;
    } elsif(($url =~ /\?/) || ($url =~ /\&/) || ($url =~ / /)) {
        $self->log($uid, sprintf("WARNING! REQUEST_CGI contains invalid characters! It may cause problems. Group: %s. URL: %s", $server_info{GROUPNAME}, $server_info{REQUEST_CGI}));
    }
    
    push(@result, $url);
    my %parameters = ();
    
    $parameters{$server_info{TARGET_NAME_KEY}} = $target_info{NAME};
    $parameters{$server_info{SEQUENCE_KEY}} = $self->format_sequence($target_info{NAME}, $target_info{SEQUENCE}, $server_info{SEQUENCE_FORMAT},$target_info{SUBUNIT});
    $parameters{$server_info{EMAIL_KEY}} = $LOCAL_CONFIG->{SERVERS_DISTRIBUTION_EMAIL};
    if (defined($server_info{STOICHIOMETRY_KEY}) && String::trim($server_info{STOICHIOMETRY_KEY}) ne ''){
      $parameters{$server_info{STOICHIOMETRY_KEY}} = $target_info{STOICHIOMETRY};   # stoichiometry
    }

    if($is_qa_request && $groups_manager->is_qa_server($groups_id)) {
        $parameters{$server_info{TARBALL_KEY}} = sprintf("%s/%s.stage%1d.3D.srv.tar.gz", $LOCAL_CONFIG->{QA_TARBALL_LOCATION}, $targets_manager->name($targets_id), $is_qa_request);   # tarball
    }

    # add additional parameter - location of the file for assisted targets
    if ($target_info{NAME} =~ m/^[NSFAXL]/){
        if (defined($server_info{ADDFILE_KEY}) && String::trim($server_info{ADDFILE_KEY}) ne ''){
		$parameters{$server_info{ADDFILE_KEY}} = sprintf("%s/%s.tar.gz", $LOCAL_CONFIG->{EXTRA_EXP_TARBALL_LOCATION}, $target_info{NAME});
        }
    } elsif ($target_info{NAME} =~ m/^R/){
        if (defined($server_info{ADDFILE_KEY}) && String::trim($server_info{ADDFILE_KEY}) ne ''){
                $parameters{$server_info{ADDFILE_KEY}} = sprintf("%s/%s.pdb.txt", $LOCAL_CONFIG->{EXTRA_EXP_TARBALL_LOCATION}, $target_info{NAME});
        }
    }   

    if(String::trim($server_info{OTHER}) ne '') {
        my @pairs = split(/&/, $server_info{OTHER});
        
        foreach my $pair (@pairs) {
            my ($name, $value) = split(/=/, $pair);
            $parameters{$name} = $value;
        }
    }
    
    push(@result, [%parameters]);
    
    return @result;
}

# work around the https servers
# at predictioncenter.org we had a problem with processing requests for https
# remedy: redirect the request to predictioncenter5 (128.120.136.155)
# and post request from it
sub redirect_post_request_for_https {
    my ($self, $refPostPars) = @_;
    my @pars = @{$refPostPars};
    my $url = $pars[0]; # predictors' server url
    my @parameters = @{$pars[1]};
    push @parameters, 'REQUEST_CGI';
    push @parameters, $url;
    my @result;
    push @result, 'http://128.120.136.155/aux/forward_https.cgi';
    push(@result, [@parameters]);
    return @result;
}

sub build_email_request {
    (@_ == 5) || die("Invalid arguments supplied");
    my ($self, $targets_id, $groups_id, $uid, $is_qa_request) = @_;
    
    my $result = "";
    
    my $targets_manager = new TargetsManager();
    my $groups_manager = new GroupsManager();
    
    my %target_info = $targets_manager->info($targets_id);
    my %server_info = $groups_manager->info_server($groups_id);
    
    $result = sprintf("%s%s=%s\n", $result, $server_info{TARGET_NAME_KEY}, $target_info{NAME});
    $result = sprintf("%s%s=%s\n", $result, $server_info{SEQUENCE_KEY}, $self->format_sequence($target_info{NAME}, $target_info{SEQUENCE}, $server_info{SEQUENCE_FORMAT},$target_info{SUBUNIT}));
    $result = sprintf("%s%s=%s\n", $result, $server_info{EMAIL_KEY}, $LOCAL_CONFIG->{SERVERS_DISTRIBUTION_EMAIL});
    if (defined($server_info{STOICHIOMETRY_KEY}) && String::trim($server_info{STOICHIOMETRY_KEY}) ne ''){
      $result = sprintf("%s%s=%s\n", $result, $server_info{STOICHIOMETRY_KEY}, $target_info{STOICHIOMETRY});   # stoichiometry
    }
    #$result = sprintf("%sCASP9_ID=%s\n", $result, $uid);
    
    if($is_qa_request && $groups_manager->is_qa_server($groups_id)) {
        $result = sprintf("%s%s=%s/%s.stage%1d.3D.srv.tar.gz\n", $result, $server_info{TARBALL_KEY}, $LOCAL_CONFIG->{QA_TARBALL_LOCATION}, $targets_manager->name($targets_id), $is_qa_request);
    }
   
    # add additional parameter - location of the file for assissted targets
    if ($target_info{NAME} =~ m/^[SNFAXL]/){
        if (defined($server_info{ADDFILE_KEY}) && String::trim($server_info{ADDFILE_KEY}) ne ''){
                $result = sprintf("%s%s=%s/%s.tar.gz\n", $result, $server_info{ADDFILE_KEY}, $LOCAL_CONFIG->{EXTRA_EXP_TARBALL_LOCATION}, $target_info{NAME});
        }
    } elsif ($target_info{NAME} =~ m/^R/){
        if (defined($server_info{ADDFILE_KEY}) && String::trim($server_info{ADDFILE_KEY}) ne ''){
		$result = sprintf("%s%s=%s/%s.pdb.txt\n", $result, $server_info{ADDFILE_KEY}, $LOCAL_CONFIG->{EXTRA_EXP_TARBALL_LOCATION}, $target_info{NAME});
        }
    }

 
    if(String::trim($server_info{OTHER}) ne '') {
        my @pairs = split(/&/, $server_info{OTHER});
        
        foreach my $pair (@pairs) {
            my ($name, $value) = split(/=/, $pair);
            $result = sprintf("%s%s=%s\n", $result, $name, $value);
        }
    }
    
    return $result;
}

sub format_sequence {
    (@_ == 5) || die("Invalid arguments supplied");
    my ($self, $target_name, $sequence, $type, $subunit) = @_;
    
    my @seqs = splitSequences($sequence);
    my $su_index = 1;
    foreach my $seq (@seqs) {
	my $fasta_header; 
	if ($target_name =~ m/^H/) {
		$fasta_header = sprintf(">%s%s|\n", $target_name,",subunit$su_index");
	} elsif ($target_name =~ m/s\d/) {
		$fasta_header = sprintf(">%s%s|\n", $target_name,",subunit$subunit");
	} else {
		$fasta_header = sprintf(">%s|\n", $target_name);
	}
	$seq =~ s/>.*\n+/$fasta_header/;
	#$seq =~ s/\s//g;
	$su_index++;
    }
#    if ($subunit =~ m/^[1-9]$/ && $subunit <= scalar(@seqs)) {
#	@seqs = ($seqs[$subunit-1]);
#    }
    $sequence = join ('', @seqs);
    
    #$sequence = validate_sequence($sequence);
    
    
    if($type ne 'fasta' && $target_name !~ m/^H/) {
	$sequence =~ s/^>.*\|\n+//;
	$sequence =~ s/\s+$//;
    }
    
    return $sequence;
}

sub save_request {
    (@_ == 3) || die("Invalid arguments supplied");
    my ($self, $uid, $request) = @_;
    
    my $result = 0;
    
    my $file = sprintf("%s/%s.request", $LOCAL_CONFIG->{REQUEST_DIR}, $uid);
    
    $result = $self->save_file($file, $request);
    
    return $result;
}

sub save_response {
    (@_ == 3) || die("Invalid arguments supplied");
    my ($self, $uid, $response) = @_;
    
    my $result = 0;
    
    my $file = sprintf("%s/%s.response", $LOCAL_CONFIG->{RESPONSE_DIR}, $uid);
    
    $result = $self->save_file($file, $response);
    
    return $result;
}

sub save_file {
    (@_ == 3) || die("Invalid arguments supplied");
    my ($self, $file, $content) = @_;
    
    my $result = 0;
    
    if(open(FILE_HANDLER, sprintf("> %s", $file))) {
        print(FILE_HANDLER $content);
        close(FILE_HANDLER);
        
        $result = 1;
    }
    
    return $result;
}

sub log {
    my ($self, $uid, $message) = @_;
    
    $self->{_logger}->info("Distribution.pm", sprintf("%-40s%s", $uid, $message));
}

sub receive_response {
    my ($self, $email, $target, $subject) = @_;
    
    my $result = '';
    
    my $groups_manager = new GroupsManager();
    my $group_id = $groups_manager->get_server_group_id_by_request_email($email);
    
    if($group_id <= 0) {
        $group_id = $groups_manager->get_server_group_id_by_response_email($email);
        if($group_id <= 0) {
            $group_id = $groups_manager->get_http_server_group_id_by_name($subject);
            if($group_id <= 0) {
                $self->log('', sprintf("ERROR! Server by email %s wasn't found!", $email));
                return $result;
	    }
        }
    }
    
    my $targets_manager = new TargetsManager();
    my $target_id = $targets_manager->get_id_by_name($target);
    
    my $jobs_manager = new JobsManager();
    my %job = $jobs_manager->get_job($group_id, $target_id);
    
    if(! scalar(%job)) {
        $self->log('', sprintf("ERROR! No job was found for the group with id %s (target %s)!", $group_id, $target));
        return $result;
    } elsif($job{STATUS} == 3) {
        $self->log('', sprintf("WARNING! Group with id %s Already responded (target %s)!", $group_id, , $target));
        return $result;
    } elsif($job{STATUS} != 2) {
        $self->log('', sprintf("ERROR! Invalid job for the group with id %s (target %s) was found!", $group_id, $target));
        return $result;
    }
    
    $jobs_manager->response($job{ID});
    
    $result = $job{UID};
    
    return $result;
}


# recieve response from one e_mail  either request_email or respond_email
# update status to all server groups associated with this e_mail
sub receive_response_from_common_email {
    my ($self, $email, $target, $subject) = @_;

    my $result = '';

    my $groups_manager = new GroupsManager();
    my @group_ids = $groups_manager->get_all_server_group_ids_by_email($email);

    if(scalar(@group_ids) <= 0) {
            my $group_id = $groups_manager->get_http_server_group_id_by_name($subject);
            if($group_id <= 0) {
                $self->log('', sprintf("ERROR! Server by email %s wasn't found!", $email));
                return $result;
            }else{
		push(@group_ids,$group_id);
	    }
    }

    my $targets_manager = new TargetsManager();
    my $target_id = $targets_manager->get_id_by_name($target);

    my $jobs_manager = new JobsManager();

    foreach my $group_id (@group_ids){
    my %job = $jobs_manager->get_job($group_id, $target_id);

    if(! scalar(%job)) { # if empty hash
        $self->log('', sprintf("ERROR! No job was found for the group with id %s (target %s)!", $group_id, $target));
        next; #return $result;
    } elsif($job{STATUS} == 3) {
        $self->log('', sprintf("WARNING! Group with id %s Already responded (target %s)!", $group_id, , $target));
        next; #return $result;
    } elsif($job{STATUS} != 2) {
        $self->log('', sprintf("ERROR! Invalid job for the group with id %s (target %s) was found!", $group_id, $target));
        next; #return $result;
    }

    $jobs_manager->response($job{ID});
    
    $result = $job{UID};
    }

    return $result;
}


sub DESTROY {
    my ($self) = @_;
    # not implemented yet
}



1;
