use utf8;
use Getopt::Long 'GetOptions';
use POSIX 'strftime';
binmode STDOUT, ':encoding(utf8)';

$version = "5.0";
$svn = "svn";
$git = "git";
$out_header = "svnversion.h";
$out_bat = "sourcetree_info.bat";
$out_cmake = "";
$source_root = "..";
$date = strftime "%Y%m%d", localtime;
$time = strftime "%H%M%S", localtime;
$verbose = 0;
$script_name = $0;

sub read_toolinfo {
	my $info = "toolinfo.txt";
	if (!-f $info) {
		return;
	}
	open(my $FD, "<:utf8:crlf", $info);
	while (my $l = <$FD>) {
		chomp $l;
		$str =~ s/^\x{FEFF}//;	# remove BOM
		if ($l =~ /^#/) {
			next;
		}
		if ($l =~ /^svn=\s*(.*)$/) {
			$svn = $1;
		}
		if ($l =~ /^git=\s*(.*)$/) {
			$git = $1;
		}
	}
	close($FD);
}

&read_toolinfo();

GetOptions(
	'root=s' => \$source_root,
	'svn=s' => \$svn,
	'git=s' => \$git,
	'header=s' => \$out_header,
	'bat=s' => \$out_bat,
	'cmake=s' => \$out_cmake,
	'verbose' => \$verbose
);

$git =~ s/"//g;
$git =~ s/\\/\//g;
$svn =~ s/"//g;
$svn =~ s/\\/\//g;

if ($verbose != 0) {
	print "root=$source_root\n";
	print "svn=\"$svn\"\n";
	print "git=\"$git\"\n";
	print "header=$out_header\n";
	print "bat=$out_bat\n";
	print "cmake=$out_cmake\n";
}

$header = "This file was generated by svnrev_perl/svnrev.pl";

if (-d "$source_root/.svn" && $svn ne "") {
	# svn infoを実行、出力をすべて取り込む
	if (!open(my $FD, "-|", "\"$svn\" info $source_root 2>&1")) {
		# svn が実行できない
		print "$script_name: '$svn' can not execute\n";
	}
	else {
		# 出力をすべて取り込む
		my $text = do { local $/; <$FD> };
		close($FD);

		# 必要な情報を取り込む
		my @text = split(/[\r\n]+/, $text);
		foreach my $l (@text) {
			if ($l =~ /Last Changed Rev: (\d+)/) {
				$svninfo{'Revision'} = $1;
			} elsif ($l =~ /Relative URL: (.+)$/) {
				my $url = $1;
				my $name = $url;
				$name =~ s/^\^\/(.*)$/$1/; # "\/" を削除する
				$svninfo{'name'} = $name;
				my $release = 0;
				if ($url =~ /tags\/(teraterm-(\d+)_(\d+))/) {
					# パス名からリリースと判定
					my $tag = $1;
					my $version = "$2.$3";
					$release = 1;
				}
				$svninfo{'release'} = $release;
			}
		}
	}
}
elsif(-d "$source_root/.git" && $git ne "") {
	my $branch = `\"$git\" rev-parse --abbrev-ref HEAD`;
	if ($branch eq '') {
		# git が実行できない
		print "$script_name: \"$git\" can not execute\n";
	}
	else {
		$branch =~ s/[\r\n]$//g;
		$svninfo{'name'} = $branch;


		if (-d "$source_root/.git/svn") {
			# use git svn log
			my $revision = `\"$git\" svn log --oneline -1`;
			$revision =~ s/^r(\d+).*$/$1/;
			$svninfo{'Revision'} = $1;
		}
		else {
			$svninfo{'Revision'} = undef;
		}

		my $release = 0;
		if ($branch =~ /tags\/(teraterm-(\d+)_(\d+))/) {
			# リリースと判定
			my $tag = $1;
			my $version = "$2.$3";
			$release = 1;
		}
		$svninfo{'release'} = $release;
	}
}
else {
	# do not use VCS
}

if ($svninfo{'release'} != 1) {
	$svninfo{'release'} = 0;
}
local $revision = $svninfo{'Revision'};

# output for source(C,C++) header
open(my $FD, ">$out_header") || die "error $out_header";
print $FD "/* $header */\n";
print $FD "/* #define TT_VERSION_STR \"$version\" check teraterm/common/tt-version.h */\n";
if ($revision == undef) {
	print $FD "#undef SVNVERSION\n";
} else {
	print $FD "#define SVNVERSION $revision\n";
}
if ($svninfo{'release'}) {
	print $FD "#define TERATERM_RELEASE 1\n";
} else {
	print $FD "#undef TERATERM_RELEASE\n";
}
print $FD "#define BRANCH_NAME \"$svninfo{'name'}\"\n";
close($FD);

# output for bat file
open(my $FD, ">$out_bat") || die "error $out_bat";
print $FD "\@rem $header\n";
print $FD "set VERSION=$version\n";
if ($revision == undef) {
	print $FD "set SVNVERSION=unknown\n";
} else {
	print $FD "set SVNVERSION=$revision\n";
}
print $FD "set RELEASE=$svninfo{'release'}\n";
print $FD "set DATE=$date\n";
print $FD "set TIME=$time\n";
close($FD);

# output for cmake
if ($out_cmake ne "") {
	open(my $FD, ">$out_cmake") || die "error $out_cmake";
	print $FD "# $header\n";
	print $FD "set(VERSION \"$version\")\n";
	if ($revision == undef) {
		print $FD "#set(SVNVERSION \"0000\")\n";
	} else {
		print $FD "set(SVNVERSION \"$revision\")\n";
	}
	print $FD "set(RELEASE $svninfo{'release'})\n";
	print $FD "set(DATE \"$date\")\n";
	print $FD "set(TIME \"$time\")\n";
	close($FD);
}
