use strict;
use warnings;

use Cwd;
use List::Util qw(min);

my $threshold=0.4;				#閾値
my $filename;
my @person;
my @dividename;
my $namemailline;
my $firstname;
my $lastname;
my $fullname;
my $firstlevenshtein;
my $lastlevenshtein;
my $fulllevenshtein;
my @mail;
my @name;
my @namemaillevenshtein;
my $similar1;
my $similar2;
my $similar3;
my @namemailline;
my @mailline;
my $mailname;
my $average;
my $maillevenshtein;
my $mail;
my @levenshteindata;
my @similar;
my $similarmax=0;
my $remChar = ">|<|\|";


my $i=0;
my $j;
my $k;
my $x=1;

my $str1;
my $str2;

&pickupname();
&examine();
#&levenshtein();
#&max();


#--------------------------------------------------------------------------------

#順番に比較対象を
sub pickupname {
	$filename=$ARGV[0];
	open FILE,"$filename";
	while($_=<FILE>){
		if($_ !~ /^0/){
			@person = split(/\t/,$_);
#person[0]=<数字>		person[1]=<key>		person[2]=<名前>		person[3]=<アドレス>	
#print "$person[3]\n";
			
			
			# 亀井追加（変数の初期化）
				$firstname = "";
				$lastname = "";
				$fullname = "";
			
			@dividename = split(/ /,$person[2]);
			if(@dividename == 1){#１wordだったとき
				if($person[2]=~ /[a-zA-Z0-9\.\-\_\$]+\@[a-zA-Z0-9\.\-\_]+/){#アドレスだった時
					@namemailline = split(/@/,$person[2]);	#＠の前後で分けた
					$fullname = $namemailline[0];
					#print "$fullname\n";
				}
				else{#アドレス以外の１wordだったとき
					$fullname = $person[2];
					#print "$fullname\n";
				}
			}
			elsif(@dividename == 2){#２wordだったとき
				$firstname = $dividename[0];
				$lastname = $dividename[1];
				$fullname = $person[2];
				#print "$fullname\n";
			}
			elsif(@dividename == 3){   #Jess M. Holleなどのミドルネームがある人対象だが、aaa bbb cccみたいなやつもひっかかる
				$firstname = $dividename[0];
				$lastname = $dividename[2];
				$fullname = $person[2];
				#print "$fullname\n";
			}
			else{#４word以上の人
				$fullname = $person[2];
				#print "$fullname\n";
 			}
			
			@mailline = split(/@/,$person[3]);	#＠の前後で分けた
			$mailname = $mailline[0];
			
#################################################
#名前にいろいろある・・・
#Sander Holthaus Orange XL
#Jess M. Holle
#ranier
#pradeep kumar
#rbowen@rcbowen.com#など。。。以下名前をfirstname,lastname,fullnameに分けられたとして考える 
#################################################

			$firstname =~ s/$remChar//g;
			$name[$i][0] = $firstname;

			$lastname =~ s/$remChar//g;
			$name[$i][1] = $lastname;

			$fullname =~ s/$remChar| //g;
			$name[$i][2] = $fullname;

			$mailname =~ s/$remChar//g;
			$mail[$i] = $mailname;

                        for (my $k = 0; $k <= 2; $k++) {
                            if($name[$i][$k] eq ''){
				$name[$i][$k] = ' ';#############################################################
                            }
                        }
			if($mail[$i] eq ''){
				$mail[$i] = ' ';#############################################################
			}

			$name[$i][3] = $person[1];

			$i++;
			
		}
		
	}
	close (FILE);
}

sub examine{
	
	for($j=0; $j<($i-1); $j++){
#		for($k=$j+1; $k<=($i-1); $k++){
		for($k=$j+1; $k<=($i-1); $k++){

		#print "aaaaaaaaaaaaaaaaaa	j=$name[$j][0]	k=$name[$k][0]\n";

			#名前同士チェック
#			$firstlevenshtein = levenshtein($name[$j][0], $name[$k][0]);	#firstname同士で比較
#			$lastlevenshtein = levenshtein($name[$j][1], $name[$k][1]);	#lastname同士で比較
#			$fulllevenshtein = levenshtein($name[$j][2], $name[$k][2]);	#fullname同士で比較


			($firstlevenshtein, $lastlevenshtein, $fulllevenshtein, $maillevenshtein, $namemaillevenshtein[0], $namemaillevenshtein[1], $namemaillevenshtein[2])
                            = levenshtein($name[$j][0], $name[$k][0],
                                          $name[$j][1], $name[$k][1],
                                          $name[$j][2], $name[$k][2],
                                          $mail[$j], $mail[$k],
                                          $mail[$j], $name[$k][0],
                                          $mail[$j], $name[$k][1],
                                          $mail[$j], $name[$k][2]);

                        if ($name[$j][0] eq ' ' and $name[$k][0] eq ' ') {
                            $firstlevenshtein = 0;
                        }
                        if ($name[$j][1] eq ' ' and $name[$k][1] eq ' ') {
                            $lastlevenshtein = 0;
                        }
                        if ($name[$j][2] eq ' ' and $name[$k][2] eq ' ') {
                            $fulllevenshtein = 0;
                        }


                        if(1) { ##<<<<<<!!!!!!!!!!!!!!!######<<<<<<<<<<< デバッグ実行以外なら簡素出力
                            $average = ($firstlevenshtein + $lastlevenshtein)/2;
                            my $max = min($average, $fulllevenshtein, $maillevenshtein, $namemaillevenshtein[0], $namemaillevenshtein[1], $namemaillevenshtein[2]);
                            #if ($max >= $threshold) {
                                print "$j	$k	$name[$j][3]	$name[$k][3]	$max\n";
                            #}
                            next;
                        }
                        ##<<<<<<!!!!!!!!!!!!!!!######<<<<<<<<<<<


#                                          "\"$mail[$j]\"", "\"$name[$k][0]\"",
#                                          "\"$mail[$j]\"", "\"$name[$k][1]\"",
#                                          "\"$mail[$j]\"", "\"$name[$k][2]\"");	#firstname同士で比較

#                    print "&&", $name[$j][3],"\t",  $name[$k][3], "\n";
#                    print "++", $name[$j][0],"\t:\t",  $name[$k][0], "\n";
#                    print "++", $name[$j][1],"\t:\t",  $name[$k][1], "\n";
#                    print "++", $name[$j][2],"\t:\t",  $name[$k][2], "\n";
#                    print "++", $mail[$j],"\t:\t",  $mail[$k], "\n";

#                    print "++", $firstlevenshtein,"\t", $lastlevenshtein,"\t", $fulllevenshtein, "\t", $maillevenshtein, "++\n";
#################################################################################################
#
#�@firstnameの類似度($first)　と　lastnameの類似度($last)　の平均($avarage)
#�A�@とfullnameの類似度を比較
#�B閾値より大きければ表示
#
#################################################################################################
			$average = ($firstlevenshtein + $lastlevenshtein)/2;
			#print "$firstlevenshtein	$lastlevenshtein	$fulllevenshtein	$average\n";

			if($average < $fulllevenshtein){
			#print "full ========== $fulllevenshtein\n";
                                print "similar1	first-last	$j	$k	$name[$j][3]	$name[$k][3]	\"first1:$name[$j][0] \"	\"first2:$name[$k][0] \"	\"last1:$name[$j][1] \"	\"last2:$name[$k][1] \"	averagename	$average\n";
			}
			else{
                                print "similar1	fullname	$j	$k	$name[$j][3]	$name[$k][3]	\"full1:$name[$j][2] \"	\"full2:$name[$k][2] \"	\"\"	\"\"	\"\"	$fulllevenshtein\n";
			}
			
			
			
			#メール同士チェック
#                        ($maillevenshtein) = levenshtein($mail[$j], $mail[$k]);
                        print "similar3	mail	$j	$k	$name[$j][3]	$name[$k][3]	\"mail1:$mail[$j] \"	\"mail2:$mail[$k] \"	\"\"	\"\"	\"\"	$maillevenshtein\n";
			
			
#                         $namemaillevenshtein[0] = 0;
#                         $namemaillevenshtein[1] = 0;
#                         $namemaillevenshtein[2] = 0;

			#名前とメールチェック
# 			if(length($mail[$j]) >= 2){	#２文字以上
# 				if(length($name[$k][0]) >= 2){
# 					($namemaillevenshtein[0]) = levenshtein($mail[$j], $name[$k][0]);
# 				}
# 				if(length($name[$k][1]) >= 2){
# 					($namemaillevenshtein[1]) = levenshtein($mail[$j], $name[$k][1]);
# 				}
# 				if(length($name[$k][2]) >= 2){
#                                         ($namemaillevenshtein[2]) = levenshtein($mail[$j], $name[$k][2]);
# 				}
#				
# 			}


			#print "aaaaaaaaaaa$namemaillevenshtein[0]	$namemaillevenshtein[1]	$namemaillevenshtein[2]\n";
#			@levenshteindata = ($namemaillevenshtein[0],$namemaillevenshtein[1],$namemaillevenshtein[2]);
			#print "ccccccccccccccc	$namemaillevenshtein[0]	$namemaillevenshtein[1]	$namemaillevenshtein[2]\n";
			$similar2 = min($namemaillevenshtein[0],$namemaillevenshtein[1],$namemaillevenshtein[2]);
                            print "similar2	namemail	$j	$k	$name[$j][3]	$name[$k][3]	\"mail:$mail[$j] \"	\"first2:$name[$k][0] \"	\"last2:$name[$k][1]\"	\"full2:$name[$k][2]\"	\"\"	$similar2\n";
			
			
# 			@similar = ($similar1,$similar2,$similar3);
# 			$similarmax = max($similar[0],$similar[1],$similar[2]);
# 			if($similarmax == $similar1){
# 				if($flag == 1){
# 					#print "similar1	first-last	first1:$name[$j][0]	first2:$name[$k][0]	last1:$name[$j][1]	last2:$name[$k][1]	averagename	$average\n";
# 				}
# 				elsif($flag == 2){
# 					#print "similar1	fullname	full1:$name[$j][0]	full2:$name[$k][0]	$fulllevenshtein\n";
# 				}
# 				#else{
# 				#	print "error\n";
# 				#}
# 			}
# 			elsif($similarmax == $similar2){
# 				#print "similar2	namemail	mail:$mail[$j]	name:$name[$k][0]	$similar2\n";
# 			}
# 			elsif($similarmax == $similar3){
# 				#print "similar3	mail	mail1:$mail[$j]	mail2:$mail[$k]	$maillevenshtein\n";
# 			}
		}
	}
	exit;
}


#levenshtein("aaaaa", "bbbbbb", "ccc cc", "dd\" ddd");

sub levenshtein
{
    my @args = @_;
    my @result = ();

    for (my $i = 0; $i <= $#args; $i+=2) {
        my $s1 = $args[$i];
        my $s2 = $args[$i+1];

        my ($len1, $len2) = (length $s1, length $s2);

        if ($len1 == 0) {
            push(@result, $len2);
            next;
        }
        if ($len2 == 0) {
            push(@result, $len1) ;
            next;
        }

        my %mat;
        
        for (my $i = 0; $i <= $len1; ++$i){
            for (my $j = 0; $j <= $len2; ++$j){
                $mat{$i}{$j} = 0;
                $mat{0}{$j} = $j;
            }
            $mat{$i}{0} = $i;
        }
        
        my @ar1 = split(//, $s1);
        my @ar2 = split(//, $s2);
        
        for (my $i = 1; $i <= $len1; ++$i) {
            for (my $j = 1; $j <= $len2; ++$j) {
                my $cost = ($ar1[$i-1] eq $ar2[$j-1]) ? 0 : 1;
                $mat{$i}{$j} = minLev([$mat{$i-1}{$j} + 1,
                                    $mat{$i}{$j-1} + 1,
                                    $mat{$i-1}{$j-1} + $cost]);
            }
        }
        push(@result, $mat{$len1}{$len2});
    }
    return @result;
}
sub minLev
{
    my @list = @{$_[0]};
    my $min = $list[0];
    foreach my $i (@list) {
        $min = $i if ($i < $min);
    }
    return $min;
}



sub levenshtein2{
    my @args = @_;


    my @list = ();
    foreach (@args) {
#        print $_, "\n";
        $_ =~ s/\"/\\"/g;
        $_ =~ s/\\/\\\\"/g;
        push(@list, "\"$_\"");
    }
#    print @list, "\n";

	# 変数定義
 	my $wd = Cwd::getcwd(); # カレントディレクトリ
 	my $jarname = $wd . "/multiLevenshtein.jar"; # levenshtein距離を計算するコア部分


###############################################################jarが実行されない
	# jarファイルの実行
 	my $result = `java -jar $jarname @list`;
	chomp($result); # 改行除去
	
	if($result =~ /Performs/){
	  $result=-1;
	}
 	# 出力 
	return(split / /, $result);
	#return(1);				#################################今は代わりに１を返すようになっている
}


