#!perl
use Cwd;
use File::Copy;

# File build_exe.pl
$Version = "0.2";

# Authors: Luc Meriaux     (LM)
#        : Bhaskar G       (BG)
#
# Support: SDE2 Team
#
# Revision History:
# -----------|---------|------------------------------------------
# Date       | Version | Description
# -----------|---------|------------------------------------------
# 2006-04-28 | 0.1, LM | Initial script
#            |      BG |
# -----------|---------|------------------------------------------
# 2006-05-03 | 0.2, BG | Comments from Luc
# -----------|---------|------------------------------------------
# Initialise variables
my $ConfigFile			="configurations.txt";
my $DiversityFile		="diversity.mk";
my $DiversityBackupFile ="diversity_bak.mk";
my $Makefile			="makefile";
my $OverwriteFile;
my %diversities			= ();
my %blankdiversitysupported	= ();
$format1				= '*' x80;

# Check for the existance of the following files: makefile and configurations.txt 
# in the current directory
sub check_component{
if ( ! -e "$Makefile" || ! -e $ConfigFile )
{
  print "$Makefile or $ConfigFile does not exist in the current directory\n";
  exit 1;
}
}

sub check_diversity_file {
if ( -e $DiversityFile )
{
  print "$DiversityFile: File exists\n";
  print "\nDo you want to overwrite this file?\n";
  print "Y(es)/N(o)/R(ename): ";
  $OverwriteFile = <STDIN>;
  print "\n";
  chomp $OverwriteFile;
  if ($OverwriteFile =~ /^yes$/i || $OverwriteFile =~ /^y$/i) {
	  print "Backing up ${DiversityFile} as ${DiversityBackupFile}\n\n";
	  copy($DiversityFile, $DiversityBackupFile);
	  $generate_diversity = 1;
  }
  elsif ($OverwriteFile =~ /^rename$/i || $OverwriteFile =~ /^r$/i) {
	  print "Enter the Filename: ";
	  $DiversityFile = <STDIN>;
	  chomp $DiversityFile;
	  $generate_diversity = 1;
  }
  else {
  	  print "Exiting\n";
	  exit 0;
  }
}
}

sub generate_diversity_file {
# Initialisation of the suffix of the component
# Get the name of the component
@list_dirs=split(/\//,cwd());
$comp_name=$list_dirs[$#list_dirs];
# Analyse the file configurations.txt
open CONFIG,"<$ConfigFile" or die "Unable to open $ConfigFile\n";

# Concatenete all diversities onto a single string
CONFIG: while ($Line = <CONFIG>) 
{
  $Line =~ s/\s+//g;            # strip all the spaces
  $Line =~ s/\t+//g;            # strip all the tabs
  last CONFIG if ( $Line =~ /EXECUTABLE/ ); # get only component diversties
  next CONFIG if $Line =~ /^\#/;  # skip comments lines
  next CONFIG if $Line !~ /~/;   # skip lines which do not contain ~
  chomp ($Line);
  @columns=split /~/, $Line;
  # concatenation
  $cpu=$columns[4];
  $os=$columns[2];
  $cpuos="${cpu}_${os}";
  $blankdiversitysupported{$cpuos}=1 if $columns[5] =~ /^[\s]*$/;
  push( @{$diversities{$cpuos}}, $columns[5]) if $columns[5] !~ /^[\s]*$/;
  # storing the information for future use
}
close CONFIG;

foreach $cpuos (sort keys %diversities) {
push (@all_diversities,@{$diversities{$cpuos}});
}

if (@all_diversities!=0) {
unless (open DIVERSITY,">$DiversityFile") 
{
  print STDERR "Unable to open $DiversityFile\n";
  exit 1;
}

foreach $cpuos (sort keys %diversities) {
#    print "$cpu: @{$diversities{$cpu}}\n";
    ($cpu,$os)=split (_,$cpuos);
	print DIVERSITY "ifeq (\$(_TMTGTCPUTYPE) \$(_TMTGTOS),$cpu $os)\n";
	@cpu_diversities=();
	foreach $div (@{$diversities{$cpuos}}) {
		$div =~ s/\s+//g;            # strip all the spaces
		$div =~ s/_+/_/g;
		$div =~ s/^_//g;
		$div =~ s/_$//g;
		@cpu_divs=split (/_/,$div);
			push (@cpu_diversities,@cpu_divs);
	}
	@cpu_diversities=remove_duplicate_fields_and_sort(@cpu_diversities);
	foreach $div (@cpu_diversities) {
			print DIVERSITY "ifneq (\$(findstring _${div}_,\$(_TMDIVERSITY)),)\n";
			print DIVERSITY "_${comp_name}_DIVERSITY:=\$(_${comp_name}_DIVERSITY)_${div}\n";
			print DIVERSITY "endif\n";
	}
	print DIVERSITY "endif \#ifeq (\$(_TMTGTCPUTYPE) \$(_TMTGTOS),$cpu $os)\n\n";
}

print DIVERSITY "\ndiversity::\n";
foreach $cpuos (sort keys %diversities) {
	my @f;
    ($cpu,$os)=split (_,$cpuos);
	print DIVERSITY "ifeq (\$(_TMTGTCPUTYPE) \$(_TMTGTOS),$cpu $os)\n";
		foreach $div (@{$diversities{$cpuos}}) {
			$div =~ s/\s+//g;            # strip all the spaces
			$div =~ s/_+/_/g;
			$div =~ s/^_//g;
			$div =~ s/_$//g;
			push (@f, "_${div}_ ");
			@diversity_list= sort (split /\_/,$div);
			@diversity_list=remove_duplicate_fields_and_sort(@diversity_list);
			my $e;
			print DIVERSITY "ifneq (";
			foreach $d (@diversity_list) {
				print DIVERSITY "\$(findstring _${d}_, \$(_TMDIVERSITY)) ";
				$e.= "_${d}_ ";
			}
			$e =~ s/[\s]*$//g;
			print DIVERSITY ",$e)\n";
		}
		@f=remove_duplicate_fields_and_sort(@f);
		print DIVERSITY "\t\@echo \"INFO: _TMDIVERSITY (\$(_TMDIVERSITY)) may have one of the following values @f\"\n" if $blankdiversitysupported{$cpuos}==1;;
		print DIVERSITY "\t\@echo \"ERROR: _TMDIVERSITY (\$(_TMDIVERSITY)) must have one of the following values @f\"\n" if $blankdiversitysupported{$cpuos}!=1;;
		print DIVERSITY "\t\@exit 1\n" if $blankdiversitysupported{$cpuos}!=1;
		foreach $div (@{$diversities{$cpuos}}) {
			print DIVERSITY "endif\n";
		}
	print DIVERSITY "endif \#ifeq (\$(_TMTGTCPUTYPE) \$(_TMTGTOS),$cpu $os)\n\n";
}
close DIVERSITY;
print "$DiversityFile successfully generated.\n";
print "Kindly ensure that \"diversity\" is defined as prerequisite to \"all\" target\n";
print "of the component makefile\n";
}
else {
	print "No diversity information found in $ConfigFile\n";
	print "$DiversityFile not modified\n" if ($generate_diversity eq 1);
}
}
  
################################################################################
#
# To remove duplicate fields in a list and sort
#
sub remove_duplicate_fields_and_sort
{
  @uniq=();
  %seen=();
  foreach $item (@_) 
  {
    push(@uniq, $item) unless $seen{$item}++;
  }
  
  return sort(@uniq);
}

################################################################################
#
# Program starts here
#
$string
    = qq(\n$format1
     Script for generating diversity.mk file based on configurations.txt.\n\n
     generate_diversity_mk.pl script version $Version\n 
    (c) NXP Semiconductors , 2006\n$format1\n);
print STDOUT $string;

check_component();
check_diversity_file();
generate_diversity_file();
