#!/usr/bin/perl -w

#use strict;
use Switch;
use DBI;
use Config::IniFiles;
use POSIX qw/strftime/;

require "interactionPath.pl";


#use constant SITE_ADJECTIVE => ($ENV{'DevelopmentSite'} ? 'Development': 'Live');
use constant SITE_ADJECTIVE => 'Development';


############First various sub routines are defined.############ 
############Following it the main subroutine code is at the botton of the file############


sub showUsage
{
	print "\n\nUsage: \n\tperl interactionsPathsFromSif <option> [<fileName>]\n";
	print "options:\n\t";
	print "0 - to add a new species\n\t";
	print "1 - to import ortholog data\n\t";
	print "2 - to import paralog data\n\t";
	print "3 - to import seed interactions data\n\n";
	die "";
	
}

#interaction type in sif files is in abbreviated format - 'pp','up',''down' etc. This function retrieves the
#full format.
#accepts abbreviated interaction type as argument
#returns interaction type id from db
sub getInteractionTypeForSifFormat
{
	# %interaction_types = map containing abbreviated and full forms of interaction_type as a key-value pair 
	($abbreviated_interaction_type) = @_;
	while ( ($key, $value) = each %interaction_types )
	{
		if($key eq $abbreviated_interaction_type){
			$interaction_type = $value;
			last;
		}
	}
	$interaction_type ne "" || die "$abbreviated_interaction_type may not be present in the db";
	
	#get interaction type id from the db
	return getInteractionTypeId($interaction_type); 
}

#read paralog file and import data into object and homology tables
sub importParalogData
{
	print "reading paralog data\n";
	open(paralog_file, "$fileName") || die "Error: file '$fileName' can not be opened\n";
	while(<paralog_file>){
		my $entry = $_;
		
		# strip off newline characters
			chomp $entry;
      $entry =~ s/\r//g;
      $entry =~ s/\n//g;
      
      # split the columns into 3 separate variables
      my ($obj_l, $obj_r, $score) = split("\t", $entry);
      
      # skip
      next if(!defined($score));
      next if($score =~ /D/);
      next if($score eq "");
      next if($score =~ /\%/);

		#get object id from Object for the gene accession in the first column. If it doesn't exist, insert into the table
		$obj_id_l = getObjectIdFromAccession($obj_l);
		if(isEmpty($obj_id_l)){
			$query = "INSERT INTO Object(`object_accession`, `species_id`) VALUES ('$obj_l', '$speciesIdForParalog') ON DUPLICATE KEY UPDATE object_accession='$obj_l'";
			executeDbQuery($query);
			$obj_id_l = getObjectIdFromAccession($obj_l);
		}

		#get object id from Object for the gene accession in the second column. If it doesn't exist, insert into the table	
		$obj_id_r = getObjectIdFromAccession($obj_r);
		if(isEmpty($obj_id_r)){
			$query = "INSERT INTO Object(`object_accession`, `species_id`) VALUES ('$obj_r', '$speciesIdForParalog') ON DUPLICATE KEY UPDATE object_accession='$obj_r'";
			executeDbQuery($query);		
			$obj_id_r = getObjectIdFromAccession($obj_r);
		}

		#check if the homology between the accessions is already recorded. If it is recorded already, check the scores and 
		#store the highest score. If the relation doesn't exist, insert into the homology table.
		($homology_id,$origScore) = getHomologyIdAndScore($obj_id_l,$obj_id_r,$score);
		if(isEmpty($homology_id) || $origScore < $score){
			$query = "INSERT INTO Homology(`object_id_source`,`object_id_projection`,`score`,`homology_type_id`) VALUES('$obj_id_l','$obj_id_r','$score','2')";
			executeDbQuery($query);
			print "$obj_id_l\t$obj_id_r\t$score\n";
		}		
	}
	print "Paralog data import completed\n";

}

#read ortholog file and import data into object and homology tables
sub importOrthologData
{
	print "reading ortholog data\n";
	open(paralog_file, "$fileName") || die "Error: file '$fileName' can not be opened\n";
	while(<paralog_file>){
		my $entry = $_;
		
		# strip off newline characters
		chomp $entry;
      $entry =~ s/\r//g;
      $entry =~ s/\n//g;
      
      # split the columns into 3 separate variables
      my ($obj_l, $obj_r, $score) = split("\t", $entry);
      
      # skip
      next if(!defined($score));
      next if($score =~ /D/);
      next if($score eq "");
      next if($score =~ /\%/);
 		
		#get object id from Object for the gene accession in the first column. If it doesn't exist, insert into the table
		$obj_id_l = getObjectIdFromAccession($obj_l);
		if(isEmpty($obj_id_l)){
			$query = "INSERT INTO Object(`object_accession`, `species_id`) VALUES ('$obj_l', '$speciesId1ForOrtholog') ON DUPLICATE KEY UPDATE object_accession='$obj_l'";
			executeDbQuery($query);
			$obj_id_l = getObjectIdFromAccession($obj_l);
		}
	
		#get object id from Object for the gene accession in the second column. If it doesn't exist, insert into the table
		$obj_id_r = getObjectIdFromAccession($obj_r);
		if(isEmpty($obj_id_r)){
			$query = "INSERT INTO Object(`object_accession`, `species_id`) VALUES ('$obj_r', '$speciesId2ForOrtholog') ON DUPLICATE KEY UPDATE object_accession='$obj_r'";
			executeDbQuery($query);		
			$obj_id_r = getObjectIdFromAccession($obj_r);
		}
		
		#check if the homology between the accessions is already recorded. If it is already, check the scores and
		# store the highest score. If the relation doesn't exist, insert into the homology table.
		($homology_id,$origScore) = getHomologyIdAndScore($obj_id_l,$obj_id_r);
		if(isEmpty($homology_id) || $origScore < $score){
			$query = "INSERT INTO Homology(`object_id_source`,`object_id_projection`,`score`,`homology_type_id`) VALUES('$obj_id_l','$obj_id_r','$score','1')";
			executeDbQuery($query);
			print "$obj_id_l\t$obj_id_r\t$score\n";
		}
		
	}
	print "Ortholog data import completed\n";

}

#import the seed interaction data into the database. The file is in sif format
sub importSifData
{
	print "reading seed interaction information from $fileName\n";

	open(interactions_file, "$fileName") || die "Error: file '$fileName' can not be opened\n";
	
	while(<interactions_file>){
		my $entry = $_;
		
		# strip off newline characters
		chomp $entry;
		$entry =~ s/\r//g;
    $entry =~ s/\n//g;

		# split the columns into separate variables
    my ($accession_left,$interaction_type,$accession_right) = split("\t", $entry);
    
    # skip if any of the variables are empty      
    next if(isEmpty($accession_left));
		next if(isEmpty($interaction_type));
		next if(isEmpty($accession_right));
      
    #get object_id for object in the first column
		$accession_left_id = getObjectIdFromAccession($accession_left);
		if(isEmpty($accession_left_id)){
			$query = "INSERT INTO Object(`object_accession`, `species_id`) VALUES ('$accession_left', '$speciesIdForSif')";
			executeDbQuery($query);		
			$accession_left_id = getObjectIdFromAccession($accession_left);
		}

		#get object_id for object in the second column
		$accession_right_id = getObjectIdFromAccession($accession_right);
		if(isEmpty($accession_right_id)){
			$query = "INSERT INTO Object(`object_accession`, `species_id`) VALUES ('$accession_right', '$speciesIdForSif')";
			executeDbQuery($query);		
			$accession_right_id = getObjectIdFromAccession($accession_right);
		}
		$interaction_type_id=getInteractionTypeForSifFormat($interaction_type);
		next if(isEmpty($accession_left_id) || isEmpty($accession_right_id) || isEmpty($interaction_type_id));
		
		#check if the interaction is already recorded. Write to database only if it doesn't exist already.e
		#an interaction is considered new under two conditions:	
			#a. interaction has not been recorded previously
			#b. interaction is already recorded, but by a different curator - this is not something that we need right now
				#but in the future, we may allow people other than the devs to upload the data themselves.
		$interactionId = getInteractionId($accession_left_id,$interaction_type_id,$accession_right_id,$curatorId);
		if(isEmpty($interactionId)){
			# if the interaction type is pp, automatically fill interactor_type_id_left, interactor_type_id_right and mode_of_action_id values appropriately. i.e - protein, protein, binds respectively
			if($interaction_type == "pp"){
				$interactor_type_id = getInteractorTypeId("protein");
				$mode_of_action_id = getModeOfActionId("binds");				
				$query = "INSERT INTO Interaction(`object_id_left`,`object_id_right`,`interaction_type_id`, `interactor_type_id_left`, `interactor_type_id_left`, `mode_of_action_id`, `curator_id`,`date`)
			 VALUES('$accession_left_id','$accession_right_id','$interaction_type_id','$interactor_type_id','$interactor_type_id','$mode_of_action_id','$curatorId', '".strftime("%Y-%m-%d", localtime)."')";
			}
			else{
				$query = "INSERT INTO Interaction(`object_id_left`,`object_id_right`,`interaction_type_id`,`curator_id`,`date`)
			 VALUES('$accession_left_id','$accession_right_id','$interaction_type_id','$curatorId', '".strftime("%Y-%m-%d", localtime)."')";
			}
			 executeDbQuery($query);					
		}
	}
	print "Seed interaction data import completed\n";
}

$optionId = $ARGV[0];
if($optionId ne "0" && $#ARGV != 1){
	showUsage();
}

#some initializations
$fileName = $ARGV[1];
$speciesIdForSif="";
$speciesIdForParalog="";
$speciesId1ForOrtholog="";
$speciesId2ForOrtholog="";
$curatorId = "";
%interaction_types=(pp=>"protein-protein binding",up=>"up regulation",down=>"down regulation");



switch($optionId){
	#add a new species to our database.
	case "0"
	{
		showAvailableSpecies();
		addNewSpecies(getSpeciesProperties(1));
	}
	#import ortholog information
	case "1"
	{
		print "\n\nYou are importing a file containing ortholog genes.\nMake sure you have information for both species\n";
		
		showAvailableSpecies();
		print "Species - 1. Species to which gene ids in the first column belong to";
		$speciesId1ForOrtholog = getSpeciesId(getSpeciesProperties(0));
		#$speciesId1ForOrtholog ne "" || die "species not found in our tables.\n";
		!isEmpty($speciesId1ForOrtholog) || die "";
		print "\nSpecies - 2. Species to which gene ids in the second column belong to";
		$speciesId2ForOrtholog = getSpeciesId(getSpeciesProperties(0));
		!isEmpty($speciesId2ForOrtholog) || die "";

		$speciesId1ForOrtholog ne $speciesId2ForOrtholog || die "species have to be different\n";
		print "$speciesId1ForOrtholog"."\t"."$speciesId2ForOrtholog"."\n";
		importOrthologData();
	}
	#import paralog information
        case "2"
	{		
		print "\n\nYou are importing a file containing paralog genes.\nMake sure you have the species information";
		showAvailableSpecies();
		$speciesIdForParalog = getSpeciesId(getSpeciesProperties(0));
		$speciesIdForParalog ne "" || die "";
		importParalogData();
	}
        case "3"
	{
		print "Make sure you have the following information:\n";
		print "\tspecies to which the gene accessions in the .sif file belong to\n";
		showAvailableSpecies();
		print "\tncbi id of the species\n";
		$curatorId = getCuratorId(getCuratorProperties());
		$speciesIdForSif = getSpeciesId(getSpeciesProperties(0));	
		$speciesIdForSif ne "" || die "Species id was not found for ".getSpeciesProperties(0)."\n";			
		importSifData();
	}
		else
	{
		print "Invalid inputs\n";
		showUsage();			
	}
}
