package CopyPredictionsManager;

use strict;
use warnings;

#
# Class is used for copying predictions from groups which are registered in CASPROL and CASP13
# They submit predictions as CASP13 groups and this module handles to copy files in corresponding
# directories of casprol, also makes records to database for schema casprol.
#


use Cwd 'abs_path';

use lib qw(Core);

use Configuration;
use LocalConfiguration;

use Database;
use Submission;

sub new {
    my ($class, $submission) = @_;
    my $self = {
	_database => Database->new($CONFIG->{HOSTNAME}, $CONFIG->{PORT}, $CONFIG->{DATABASE}, $CONFIG->{USERNAME}, $CONFIG->{PASSWORD}),
	_submission => $submission
    };
    
    bless $self, $class;
    return $self;
}

sub process{
    my ($self) = @_;

    my $old_file;
    my $new_file;

    # copy files
#    $old_file = $self->{_submission}->{_prediction_file} . " " ;# wierd, but it was necessary to add " ";
#    $old_file = abs_path($old_file);
#    $new_file = $old_file;
#    $new_file =~ s/CASP13/CASPROL/g;
#    $new_file =~ s/casp13/casprol/g;
#    if(! -e $new_file){
#      system("ln $old_file $new_file");
#    }
    foreach my $m (@{$self->{_submission}->{_models}}){
	if($m eq ''){next;}
#	$old_file = $self->{_submission}->{_prediction_file} . "_" .$m . " ";
#	$old_file = abs_path($old_file);
#	$new_file = $old_file;
#        $new_file =~ s/CASP13/CASPROL/g;
#	$new_file =~ s/casp13/casprol/g;
#	if(! -e $new_file){
#          if(0 != system("ln  $old_file $new_file")){ # if not ok (system return 0 if it successfully executes command)
#		return 0;
#	  }
#	}
	
	# write to directory CASPROL/predictions/accepted/
	#-----------------------------------------
	$old_file = sprintf("%s/%s%s%03d_%1d ", $LOCAL_CONFIG->{ACCEPTED_PREDICTIONS_DIR}, $self->{_submission}->{_target}, $self->{_submission}->{_pfrmat}, $self->{_submission}->{_groups_code}, $m);
	$old_file = abs_path($old_file);
	$new_file = $old_file;
	$new_file =~ s/CASP13/CASPROL/g;
	$new_file =~ s/casp13/casprol/g;
#	if(! -e $new_file){
	   if(0 != system("cp -p $old_file $new_file")){ # if not ok 
            return 0;
           }
#	}

	
	#-----------------------------------------
	
	# write to directory CASPROL/predictions/cleaned/
	#-----------------------------------------
	my $old_dir = sprintf("%s/%s", $LOCAL_CONFIG->{CLEAN_PREDICTIONS_DIR}, $self->{_submission}->{_target});
	$old_dir = abs_path($old_dir);
	my $new_dir = $old_dir;
	$new_dir =~ s/CASP13/CASPROL/g;
	$new_dir =~ s/casp13/casprol/g;
	if(! -d $new_dir){
	   system("mkdir -p $new_dir");
	   system("chmod 775 $new_dir");
	   system("chgrp casp $new_dir");
	}

	$old_file = sprintf("%s/%s/%s%s%03d_%1d ", $LOCAL_CONFIG->{CLEAN_PREDICTIONS_DIR}, $self->{_submission}->{_target}, $self->{_submission}->{_target}, $self->{_submission}->{_pfrmat}, $self->{_submission}->{_groups_code}, $m);
        $old_file = abs_path($old_file);
	$new_file = $old_file;
        $new_file =~ s/CASP13/CASPROL/g;
	$new_file =~ s/casp13/casprol/g;
#	if(! -e $new_file){
	    if(0 != system("cp -p $old_file $new_file")){ # if not ok 
	       return 0;
	    }
#	}
	  # write oligomeric predictions
	  # ++++++++++++++++++++++++++++++++++++++
	  $old_file = sprintf("%s/%so/%s%s%03d_%1do ", $LOCAL_CONFIG->{CLEAN_PREDICTIONS_DIR}, $self->{_submission}->{_target}, $self->{_submission}->{_target}, $self->{_submission}->{_pfrmat}, $self->{_submission}->{_groups_code}, $m);
	  if(-e $old_file){
		$old_dir = sprintf("%s/%so/ ", $LOCAL_CONFIG->{CLEAN_PREDICTIONS_DIR}, $self->{_submission}->{_target});
		$old_dir = abs_path($old_dir);
		$new_dir = $old_dir;
		$new_dir =~ s/CASP13/CASPROL/g;
		$new_dir =~ s/casp13/casprol/g;
		if(! -d $new_dir){
	           system("mkdir -p $new_dir");
        	   system("chmod 775 $new_dir");
	           system("chgrp casp $new_dir");
	        }
		$old_file = abs_path($old_file);
		$new_file = $old_file;
	        $new_file =~ s/CASP13/CASPROL/g;
		$new_file =~ s/casp13/casprol/g;
#		if(! -e $new_file){
                   if(0 != system("cp -p $old_file $new_file")){ # if not ok 
                      return 0;
                   }
#		}
	  }
	  # ++++++++++++++++++++++++++++++++++++++
	#-----------------------------------------

	# write data to database to schema casprol
	#-----------------------------------------

        if(0 == $self->add_predictions_log($m)){
            return 0;
        }

	if(0 == $self->add($self->{_submission}->{_email},$self->{_submission}->{_type},$self->{_submission}->{_pfrmat},$self->{_submission}->{_target},$self->{_submission}->{_groups_id}, $m, $self->{_submission}->{_predictor_id} )){
	    return 0;
	}
	#-----------------------------------------
    }
    return 1; # successful termination
}


sub add {
        my($self, $email, $type, $pfrmat, $target, $groups_id, $model_id, $predictor_id) = @_;

        my $result = 0;

        my $pid = $self->prediction_exist($target, $model_id, $pfrmat, $groups_id);

        if($pid > 0) {
                $result = $self->update($pid, $email, $type, $pfrmat, $target, $groups_id, $model_id, $predictor_id);
        } else {
                my $query = sprintf("INSERT INTO casprol.predictions (groups_id, type, email, pfrmat, target, model, predictors_id) VALUES (%d, '%s', '%s', '%s', '%s', %d, %d)", $groups_id, $type, $email, $pfrmat, $target, $model_id, $predictor_id);
                my $sth = $self->{_database}->query($query);

                if(defined($sth)) {
                        my $query = sprintf("SELECT MAX(id) FROM casprol.predictions");
                        my $sth = $self->{_database}->query($query);

                        # add logger
                        ($result) = $sth->fetchrow_array();
                }
        }

        return $result;
}

sub update {
    my ($self, $id, $email, $type, $pfrmat, $target, $groups_id, $model_id, $predictor_id) = @_;

    my $result = 0;

    my $query = sprintf("UPDATE casprol.predictions SET target = '%s', type = '%s', pfrmat = '%s', email = '%s', model = %d, groups_id = %d, predictors_id = %d, date=now() WHERE (id = %d)", $target, $type, $pfrmat, $email, $model_id, $groups_id, $predictor_id, $id);
    my $sth = $self->{_database}->query($query);

    if(defined($sth)) {
        # add logger
        $result = 1;
    }

    return $result;
}

sub prediction_exist {
        my($self, $target, $model, $pfrmat, $groups_id) = @_;

        my $result = 0;

    my $query = sprintf("SELECT id FROM casprol.predictions WHERE (target = '%s') AND (model = %d) AND (pfrmat = '%s') AND (groups_id = %d)", $target, $model, $pfrmat, $groups_id);
    my $sth = $self->{_database}->query($query);

    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }

        return $result;
}


sub add_predictions_log {
    my ($self, $model_number) = @_;

    my $casprol_target_id = $self->get_target_id_by_name_casprol($self->{_submission}->{_target});
    if($casprol_target_id <= 0 || !defined($casprol_target_id)){
	return 0;
    }

    my $file_name = sprintf("%s%s%03d_%1d ",  $self->{_submission}->{_target}, $self->{_submission}->{_pfrmat}, $self->{_submission}->{_groups_code}, $model_number);    

    my $query = sprintf("INSERT INTO casprol.predictions_log
        (date, group_id, group_name, target_id, target_name,
        model, pfrmat, status, file_name, case_id, recived_from, return, predictor_id, submission_type )
        VALUES ( now(), %s, '%s', %s, '%s', %s, '%s', '%s', '%s', '%s', '%s', '%s' , '%s', '%s' )",
	$self->{_submission}->{_groups_id}, $self->{_submission}->{_author}, $casprol_target_id, $self->{_submission}->{_target}, $model_number, $self->{_submission}->{_pfrmat}, "accepted", $file_name , $self->{_submission}->{_case_id}, $self->{_submission}->{_email}, "saved prediction", $self->{_submission}->{_predictor_id}, $self->{_submission}->{_type});

    my $sth = $self->{_database}->query($query);

    my $prediction_log_id = 0;

    if(defined($sth)) {
        my $query = sprintf("SELECT MAX(id) FROM casprol.predictions_log");
        my $sth = $self->{_database}->query($query);
        # add logger
        ($prediction_log_id) = $sth->fetchrow_array();
    }

    return $prediction_log_id;

}


sub get_target_id_by_name_casprol {
    my ($self, $target_name) = @_;

    my $result = 0;    

    my $query = sprintf("SELECT id FROM casprol.targets WHERE (name = '%s')", $target_name);
    my $sth = $self->{_database}->query($query);

    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }

    return $result;
}

1;

