#!/usr/bin/perl 
#
# dh_make - Script to Debianize a source archive
#
use Getopt::Long;
#Getopt::Long::Configure ("bundling");  
#Getopt::Long::Configure ("bundling_override");  

# Some important parameters
$DHLIB="/usr/share/debhelper/dh_make";
$POLICY_VERSION="3.5.2";
$DH_MAKE_VERSION="0.30";
%PACKAGE_TYPES = ( 's' => 'Single', 'l' => 'Library', 'm' => 'Multi-Binary');
$DASHLINE="";

$license="";
$email="";
$username="";
$package_name="";
$cap_package_name="";
$version="";
$fullname = "";
$source_file="";
$debian_native = 0;
$package_type="";
$CHANGELOG="";
$add_missing = 0;
$custom = "";
$no_defaults = 0;
$overlay = "";
my $dummy;

sub process_file(@)
{
   my ($infile, $outfile) = @_;  
   my $line;

   if ( $main::overlay eq "" )
   {
     if ( $main::add_missing && -f $outfile) {
       print "File $outfile exists, skipping.\n";
       return;
     }
   }

    open IN, "<$infile" or die "Unable to open template file $infile for reading: $! \n";
    open OUT, ">$outfile" or die "Unable to open file $outfile for writing: $! \n";
    while (defined($line = <IN>))
    {
      $line =~ s/#PACKAGE#/$main::package_name/g;
      $line =~ s/#UCPACKAGE#/$main::uc_package_name/g;
      $line =~ s/#VERSION#/$main::version/g;
      $line =~ s/#EMAIL#/$main::email/g;
      $line =~ s/#DATE#/$main::date/g;
      $line =~ s/#SHORTDATE#/$main::shortdate/g;
      $line =~ s/#CHANGELOGS#/$main::CHANGELOG/g;
	  $line =~ s/#CONFIG_STATUS#/$main::CONFIG_STATUS/g;
      $line =~ s/#CONFIGURE#/$main::CONFIGURE/g;
	  $line =~ s/#CONFIGURE_STAMP#/$main::CONFIGURE_STAMP/g;
      $line =~ s/#DPKG_ARCH#/$main::DPKG_ARCH/g;
      $line =~ s/#INSTALL#/$main::INSTALL/g;
      $line =~ s/#CLEAN#/$main::CLEAN/g;
      $line =~ s/#USERNAME#/$main::username/g;
      $line =~ s/#POLICY#/$main::POLICY_VERSION/g;
      $line =~ s/#DASHLINE#/$main::DASHLINE/g;
	  $line =~ s/#PHONY_CONFIGURE#/$main::PHONY_CONFIGURE/g;

      print OUT $line;
    }
    close IN;
    close OUT;
}

sub show_version
{
  print "dh_make - Script to Debianize a regular source archive, version $main::DH_MAKE_VERSION\n\n";
  print "Copyright (C) 1998-2002 Craig Small <csmall\@debian.org>\n";
  print "This is free software; see the source for copying conditions.  There is NO\n";
  print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
}
sub show_help
{
  show_version();
  print <<EOF
  Usage: dh_make [options]
  -c, --copyright <type>    use <type> of license in copyright file
                            (gpl|lgpl|artistic|bsd)
  -e, --email <address>     use <address> as the maintainer e-mail address
  -n, --native              the program is Debian native, don\'t generate .orig
  -f, --file <file>         specify file to use as the original source archive
  -s, --single              set package class to single
  -m, --multi               set package class to multiple binary
  -l, --library             set package class to library
  -a, --addmissing          reprocess package and add missing files
  -t, --templates <dir>      apply customizing templates in <dir>
  -d  --defaultless         skip the default debian and package class templates
  -o, --overlay <dir>       reprocess package using template in <dir>
  -h, --help                display this help screen and exit
  -v, --version             show the version and exit

By Craig Small <csmall\@debian.org>
Based on deb-make by Christoph Lameter <clameter\@debian.org>.
Custom template support by Bruce Sass <bsass\@edmc.net>.
EOF
}

sub parse_args
{
  my ($dohelp,$doversion, $single,$multi,$library );
  %options = ('copyright' => \$main::license,
              'email' => \$main::email,
              'file' => \$main::source_file,
	      'help' => \$dohelp,
	      'version' => \$doversion,
	      'native' => \$main::debian_native,
	      'single' => \$single,
	      'multi' => \$multi,
	      'library' => \$library,
	      'addmissing' => \$main::add_missing,
	      'templates' => \$main::custom,
	      'defaultless' => \$main::no_defaults,
	      'overlay' => \$main::overlay
	      );
  if (GetOptions(\%options, "copyright=s", "email=s", "file=s", "templates=s", "overlay=s", "help", "version", "native", "single", "multi", "library", "addmissing", "defaultless") == 0)
  {
    show_help();
    exit;
  }
  if ($doversion)
  {
    show_version();
    exit;
  }
  if ($dohelp)
  {
    show_help();
    exit;
  }
  if ($single)
  {
    $main::package_type = 's';
  }
  if ($multi)
  {
    $main::package_type = 'm';
  }
  if ($library)
  {
    $main::package_type = 'l';
  }
  if ($addmissing)
  {
    $main::add_missing = 1;
  }
  if ($defaultless)
  {
    $main::no_defaults = 1;
  }
  $main::license = lc $main::license;
  if ($main::lincense ne "" && grep(!/gpl|lgpl|artistic|bsd/, $main::license)) {
    print "Copyright type \"$main::license\" is not gpl, lgpl, artistic or bsd\n";
    exit;
  }

}

sub get_username
{
  my $tmpusername;

  $tmpusername = $ENV{'DEBFULLNAME'};
  return $tmpusername if ($tmpusername ne "");

  $tmpusername =`awk -F: -vUSER=$ENV{LOGNAME} '\$1 == USER \{ print \$5; \}' /etc/passwd | cut -f1 -d,`;
  chomp($tmpusername);
  return $tmpusername if ($tmpusername ne "");
  
  if (-x '/usr/bin/ypmatch')
  {
    $tmpusername=`ypmatch $ENV{LOGNAME} passwd.byname|awk -F: '\{ print \$5; \}' | cut -f1 -d,`;
  }
  chomp($tmpusername);
  return $tmpusername if ($tmpusername ne "");

  if (-x '/usr/bin/ldapsearch')
  {
    $tmpusername = [map {/^(?:gecos|cn): (.*)/} `ldapsearch -Q -LLL uid=$ENV{LOGNAME} gecos cn`]->[0];
  }
  chomp($tmpusername);
  return $tmpusername if ($tmpusername ne "");

  return "unknown";
}

sub get_email() 
{
  if (-x '/usr/bin/ldapsearch')
  {
    my $mail;
    $mail = [map {/^mail: (.*)/ && $1} `ldapsearch -Q -LLL uid=$ENV{LOGNAME} mail`]->[0];
      return $mail if $mail;
  }
  if ($ENV{DEBEMAIL} )
  {
    return $ENV{DEBEMAIL};
  }
  if ($ENV{EMAIL} )
  {
    return $ENV{EMAIL};
  }
  if ($ENV{LOGNAME} )
  {
    my $mailhost;
    if ( -e '/etc/mailname'){
      chomp($mailhost = `cat /etc/mailname`);
    } else {
      $mailhost='unknown';
    } 
    return  ($ENV{LOGNAME} . '@' . $mailhost);
  }
}

sub get_package
{
  my $pwd = `pwd`;

  if ($pwd =~ /.*\/(.*)-([0-9][0-9a-zA-Z+\.\-]*)$/)
  {
    $main::package_name = $1;
    $main::uc_package_name = uc $1;
    $main::version = $2;
    $main::fullname = $1 . "-"  . $2;
  } else {
    print "The directory name must be <package>-<version> for dh_make to work!\n";
    print "No underscores allowed!\n";
    exit 1;
  }
  if (! ($main::package_name =~ /^[a-z0-9+.-]+$/)) {
    print "Package name \"$main::package_name\" is not in a valid format.\n";
    print "Debian policy manual states:\n";
    print "   \"Package names must only consist of lower case letters, digits (0-9), plus (+)\n    or minus (-) signs, and periods (.)\"\n";
    exit 1;
  }
}

sub get_date
{
  my $tmpdate;
  if (-x "/usr/bin/822-date")
  {
    $tmpdate = `/usr/bin/822-date`;
    chomp($tmpdate);
    return $tmpdate;
  } else {
    die "Unable to find 822-date program in /usr/bin!\n";
  }
}

$username = get_username();
$email = get_email();
$date = get_date();
$shortdate = `date '+%B %e, %Y'`;
chomp $shortdate;
parse_args();
if ( ! $overlay eq "" )
{
  #setup for overlay mode
  $no_defaults = 1;
  $add_missing = 1;
  $customer = $overlay;
}
get_package();

# Generate a line of dashes, which is as long as '#PACKAGE# for Debian'.
for ($i=0; $i<length("$main::package_name for Debian"); $i++)
{
 $DASHLINE = $DASHLINE . '-';
}

if ( ! $no_defaults )
{
  while ($package_type eq "")
  {
    print "\nType of package: single binary, multiple binary, or library? [s/m/l] ";
    $type = <STDIN>;
    chomp($type);
    print "\n";
    $type = lc($type);
    $main::package_type = 's' if $type eq 's';
    $main::package_type = 'm' if $type eq 'm';
    $main::package_type = 'l' if $type eq 'l';
  }
}

# Print what we have found
print "Maintainer name : $username\n";
print "Email-Address   : $email \n";
print "Date            : $date\n";
print "Package Name    : $package_name\n";
print "Version         : $version\n";
print "Type of Package : ";
if (exists $PACKAGE_TYPES{$package_type})
{
  print $PACKAGE_TYPES{$package_type};
} else {
  print 'unknown';
}
if ( $customer ne "" )
{
  print "\nCustomer template : $custom";
}
if ( $overlay ne "" )
{
  print " (overlay)";
}
if ( $no_defaults )
{
  print "\nDefault debian and package class templates will not be applied.";
}
print "\nHit <enter> to confirm: ";
$dummy = <STDIN>;

if (! $debian_native)
{
  if ($source_file)
  {
    if (-f $source_file)
    {
      system('cp', '-a', "$source_file", "../$package_name\_$version.orig.tar.gz");
    } else {
      print "Source archive you specified was not found!\n";
      exit 1;
    }
  } else {
    if (-d "..$fullname.orig")
    {
      print "Skipping copying to $fullname.orig since $fullname.orig exists.\n";
    } else {
      system('cp', '-a', "../$fullname", "../$fullname.orig");
    }
  }
}
# Figure out where documentation is
@DOCS= split /[ \n]/, `ls -1 N[Ee][Ww][Ss] *[Ff][Aa][Qq]* *.[Tt][Xx][Tt] README* *.README [rR]eadme* *.[rR]eadme [Bb][Uu][Gg][Ss] *[tT][oO][dD][oO]* 2>/dev/null`;
# What are our info files
@INFOS= split /[ \n]/, `find . -regex '.*\\.info\\(-[0-9]+\\)?'`;
# Figure out where is the first changelog, assign other similar files to docs
@changelogs= split /[ \n]/, `ls *[cC][hH][aA][nN][gG][eE][lL][oO][gG]* [cC][hH][aA][nN][gG][eE][sS]* 2>/dev/null`;
$CHANGELOG = $changelogs[0] if ($#changelogs != -1);
shift @changelogs;
@DOCS = (@DOCS,@changelogs);

# Setup debian/rules
if (-x "./configure" )
{
  $CONFIG_STATUS="config.status";
  $CONFIGURE_STAMP='';
  $PHONY_CONFIGURE='';
  $CONFIGURE="config.status: configure\n".
             "\tdh_testdir\n".
			 "\t# Add here commands to configure the package.\n".
			 "\t".'./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info'."\n";
  $DPKG_ARCH="# These are used for cross-compiling and for saving the configure script\n".
             "# from having to guess our platform (since we know it already)\n".
			 'DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)'."\n".
			 'DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)'."\n";


  # If it is a library then install into tmp
  if ( $package_type eq "l") {
    $INSTALL="\$(MAKE) install prefix=\$(CURDIR)/debian/tmp";
  } else {
    $INSTALL="\$(MAKE) install prefix=\$(CURDIR)/debian/$package_name/usr";
  }
  $CLEAN="\$(MAKE) distclean\n".
         "\t-test -r /usr/share/misc/config.sub && \\\n".
		 "\t  cp -f /usr/share/misc/config.sub config.sub\n".
		 "\t-test -r /usr/share/misc/config.guess && \\\n".
		 "\t  cp -f /usr/share/misc/config.guess config.guess\n";
} else {
  if (! -f 'Makefile' && ! -f 'makefile' && ! -f 'GNUmakefile')
  {
    print "Currently there is no top level Makefile. This may require additional tuning.\n";
  }
  $CONFIGURE_STAMP='configure-stamp';
  $CONFIG_STATUS='';
  $CONFIGURE="configure: configure-stamp\n".
             "configure-stamp:\n". 
			 "\tdh_testdir\n".
			 "\t# Add here commands to configure the package.\n\n".
			 "\ttouch configure-stamp\n";
  $PHONY_CONFIGURE='configure';
  $DPKG_ARCH='';
  if ($package_type eq "l") {
    $INSTALL="\$(MAKE) install DESTDIR=\$(CURDIR)/debian/tmp";
  } else {
    $INSTALL="\$(MAKE) install DESTDIR=\$(CURDIR)/debian/$package_name";
  }
  $CLEAN='$(MAKE) clean';
}

# Customize files
if ( $add_missing )
{
  if ( ! -d 'debian' )
  {
    die "--addmissing  or --overlay flag used but cannot find debian subdirectory\n";
  }
} else {
  if ( ! -d 'debian')
  {
    mkdir 'debian', 0755 or die "Unable to make debian subdirectory: $! \n";
  } else {
    print "You already have a debian/ subdirectory in the source tree.\n";
    print "dh_make will not try to overwrite anything.\n";
    exit 1;
  }
}
chdir 'debian' or die "Unable to chdir to debian subdirectory: $! \n";

if ( ! -d $DHLIB )
{
die "Unable to find dh_make's template directory: $! \n";
}

if ( ! $no_defaults )
{
  # General Files
  @filenames= split /[ \n]/, `(cd $DHLIB/debian && ls)`;
  foreach $filename (@filenames)
  {
    process_file("$DHLIB/debian/$filename", $filename);
  }

  # Copyright file
  if ($license eq '') 
  {
    process_file("$DHLIB/licenses/blank", copyright);
  } else {
    if ( -r "$DHLIB/licenses/$license" )
    {
      process_file("$DHLIB/licenses/$license", copyright);
    } else {
      die "Unable to find copyright template file $DHLIB/licenses/$license";
    }
  }

  # Special Files
  @filenames = split /[ \n]/, `(cd $DHLIB/debian$package_type && ls)`;
  foreach $filename (@filenames)
  {
    process_file("$DHLIB/debian$package_type/$filename", $filename);
  }
}

# Custom template
if ( $custom ne "" )
{
  if ( -d $custom )
  {
    @filenames = split /[\n]/, `(cd $custom && ls)`;
    foreach $filename (@filenames)
    {
      process_file("$custom/$filename", $filename);
    }
  } else {
    print "Unable to find the customization directory, $custom\n";
  }
}


if ( -f "docs" )
{
  print "File docs already exists, skipping.\n";
} else {
  open (DOCSFILE,">docs");
  foreach $doc (@DOCS)
  {
    print DOCSFILE "$doc\n";
  }
  close (DOCSFILE);
}

if ( -f "info" )
{
  print "File info already exists, skipping.\n";
} else {
  if ($#INFOS > -1 )
  {
    open (INFOFILE,">info");
    foreach $info (@INFOS)
    {
      $info =~ s/^\.\///;
      print INFOFILE "$info\n";
    }
    close (INFOFILE);
  }
}

if ( ! $no_defaults )
{
  if ($debian_native)
  {
  @filenames= split /[ \n]/, `(cd $DHLIB/native;ls)`;
  foreach $filename (@filenames)
  {
      process_file("$DHLIB/native/$filename", $filename);
    }
  }
}

@filenames = split /[ \n]/, `ls package* 2>/dev/null`;
if ($#filenames != -1)
{
  foreach $filename (@filenames)
  {
    my $oldname = $filename;
    $filename =~ s/^package/$package_name/;
    if ( -f $filename)
    {
      print "File $filename already exists, skipping.\n";
    } else {
      system('mv', $oldname, $filename);
    }
  }
}
chmod 0755, 'rules';

if ($CONFIG_STATUS ne "")
{
  print "Done. Please edit the files in the debian/ subdirectory now. $package_name\n";
  print "uses a configure script, so you probably don't have to edit the Makefiles.\n";
} else {
  print "Done. Please edit the files in the debian/ subdirectory now. You should also\n";
  print "check that the $package_name Makefiles install into \$DESTDIR and not in / .\n";
}

exit 0;
