#!/usr/bin/perl

use warnings;
use strict;
use lib('tlpkg', '/usr/share/tlpkg');

use TeXLive::TLPOBJ;

my $arch = `uname -m`;
chomp($arch);
$arch = "i386" if ($arch =~ m/i[456]86/);
$arch .= "-linux";

# texlive => rpm
my %Provides = (
    'jadetex'	=>	"jadetex = %{version}",
    'kpathsea'	=>	"kpathsea = %{version}",
    'pdfjam'	=>	"pdfjam = %{version}",
    'latexdiff'	=>	"latexdiff = %{version}",
    'pstools'	=>	"ps2eps = %{version}",
    'tetex'	=>	"tetex = %{version}",
    'dvipdfm'	=>	"tetex-dvipdfm, texlive-texmf-dvipdfm = 20111101",
    'dviljk'	=>	"tetex-dvilj, texlive-dvilj = 20111101",
    'dvips'	=>	"tetex-dvips = %{version}, texlive-dvips = %{version}, texlive-texmf-dvips = %{version}",
    'xdvi'	=>	"tetex-xdvi = %{version}, xdvik = %{version}",
    'latex'	=>	"tetex-latex = %{version}, texlive-latex = %{version}, texlive-texmf-latex = %{version}",
    'afm2pl'	=>	"tetex-afm = %{version}, texlive-afm = %{version}, texlive-texmf-afm = %{version}",
    'context'	=>	"texlive-texmf-contex = %{version}",
    'scheme-tetex'=>	"texlive-dviutils = %{version}",
    'xmltex'	=>	"xmltex = 1:20111103",
    'vlna'	=>	"vlna = %{version}",
    'cm-super'	=>	"tetex-cmsuper = %{version}, texlive-texmf-cmsuper = %{version}",
    'tex4ht'	=>	"tex4ht = 1:%{version}",
    'collection-fontsextra'=>"texlive-fontsextra = %{version}",
    'collection-fontsrecommended'=>"texlive-fonts = %{version}, texlive-texmf-fonts = %{version}"
);
# to be used when using a system package
my %Requires = (
    'lcdftypetools'=> 'lcdf-typetools',
    'psutils'	=>	'psutils',
    'tex4ht'	=>	'tex4ht',
);
# the idea is to not allow other packages as alternatives, at least at
# first, so, "Obsoletes" should also "Conflicts"
my %Obsoletes = (
    'jadetex'	=>	"jadetex <= 3.12, texlive-texmf-jadetex <= 2007",
    'kpathsea'	=>	"kpathsea-devel <= 20100722, kpathsea-static-devel <= 20100722",
    'pdfjam'	=>	"pdfjam <= 1.21",
    'pstools'	=>	"ps2eps <= 1.64",
    'dvipdfm'	=>	"texlive-texmf-dvipdfm <= 2007",
    'dvips'	=>	"tetex-dvips <= 3.0, texlive-dvips <= 2007, texlive-texmf-dvips <= 2007",
    'xdvi'	=>	"tetex-xdvi <= 3.0",
    'latex'	=>	"tetex-latex <= 3.0, texlive-latex <= 2007, texlive-texmf-latex <= 2007",
    'afm2pl'	=>	"tetex-afm <= 3.0, texlive-afm <= 2007, texlive-texmf-afm <= 2007",
    'context'	=>	"texlive-contex <= 2007, texlive-texmf-contex <= 2007",
    'scheme-tetex'=>	"texlive-dviutils <= 2007",
    # correct?
    'metafont'	=>	"tetex-mfwin <= 3.0, texlive-mfwin <= 2007",
    'xmltex'	=>	"xmltex <= 1:3.0",
    'vlna'	=>	"vlna <= 1.4",
    'cm-super'	=>	"tetex-cmsuper <= 0.3.3, texlive-texmf-cmsuper <= 2007",
    'tex4ht'	=>	"tex4ht <= 1:1.0.2008_02_28_2058",
    'collection-fontsextra'=>"texlive-fontsextra < 20110705-3",
    'collection-fontsrecommended'=>"texlive-fonts <= 2007, texlive-texmf-fonts <= 2007"
);
my %special = (
  '%{_texmfdir}/web2c/fmtutil.cnf'			=>	"%config(noreplace) ",
  '%{_texmfdir}/tex/generic/config/language.dat'	=>	"%config(noreplace) ",
  '%{_texmfdir}/tex/generic/config/language.dat.lua'	=>	"%config(noreplace) ",
  '%{_texmfdir}/tex/generic/config/language.def'	=>	"%config(noreplace) ",
);

our $_tmp;
select((select(STDOUT), $~ = "multilineformat")[0]);
STDOUT->format_lines_per_page (99999);	# no pages in this format

my $tlpobj = TeXLive::TLPOBJ->new();
unless ($tlpobj->from_file($ARGV[0])) {
    die("Error initializing tlpobj.\n");
}

my $file = $ARGV[0];
$file =~ s/\.tlpobj//;
my $tlpobjdoc = undef;
if (-f "$file.doc.tlpobj") {
    $tlpobjdoc = TeXLive::TLPOBJ->new();
    $tlpobjdoc->from_file("$file.doc.tlpobj");
}
my $tlpobjsrc = undef;
if (-f "$file.source.tlpobj") {
    $tlpobjsrc = TeXLive::TLPOBJ->new();
    $tlpobjsrc->from_file("$file.source.tlpobj");
}

chomp(my $enable_asymptote = `rpm --eval "%{_texmf_enable_asymptote}"`);
chomp(my $enable_xindy = `rpm --eval "%{_texmf_enable_xindy}"`);
chomp(my $with_system_lcdf = `rpm --eval "%{_texmf_with_system_lcdf}"`);
chomp(my $with_system_psutils = `rpm --eval "%{_texmf_with_system_psutils}"`);
chomp(my $with_system_t1lib = `rpm --eval "%{_texmf_with_system_t1lib}"`);

my $revision = $tlpobj->{'revision'};
$revision = "undef" unless ($revision);
print("# revision $revision\n");
my $category = $tlpobj->{'category'};
$category = "undef" unless ($category);
print("# category $category\n");
my $ctan = $tlpobj->{'cataloguedata'}{'ctan'};
$ctan = "undef" unless ($ctan);
print("# catalog-ctan $ctan\n");
my $date = $tlpobj->{'cataloguedata'}{'date'};
$date = "undef" unless ($date);
print("# catalog-date $date\n");
my $license = $tlpobj->{'cataloguedata'}{'license'};
$license = "undef" unless ($license);
print("# catalog-license $license\n");
my $version = $tlpobj->{'cataloguedata'}{'version'};
$version = "undef" unless ($version);
print("# catalog-version $version\n");

my $relocated = $tlpobj->{'relocated'};

my $name = $tlpobj->{'name'};
print("Name:\t\ttexlive-", $name, "\n");
my $binary = 0;
if ($name =~ /(.*)\.(.*)/) {
    my $platform = $2;
    if ($platform eq $arch) {
	$name = $1 . ".bin";
	$binary = 1;
    }
}
#--
if ($version eq "undef") {
    if ($date ne "undef") {
	$version = $date;
	$version =~ m/(\d\d\d\d)-(\d\d)-(\d\d)/;
	$version = "$1$2$3";
    }
    else {
	chomp($version = `date +%Y%m%d`);
    }
}
print("Version:\t$version\n");
print("Release:\t1\n");
my $summary = $tlpobj->{'shortdesc'};
if (defined($summary) && $summary ne "") {
    $summary =~ s/\.+\s*$//;
    $summary =~ s/\b$arch\b/binary/g;
}
else {
    $summary = "TeXLive $name package";
}
print("Summary:\t$summary\n");
print("Group:\t\tPublishing\n");
#--
my $url = $tlpobj->{'cataloguedata'}{'ctan'};
if (defined($url) && $url ne "") {
    $url = "http://www.ctan.org/tex-archive$url";
}
else {
    $url = "http://tug.org/texlive";
}
print("URL:\t\t$url\n");
#--
if ($license ne "undef") {
    $license = uc($license);
}
else {
    $license = "http://www.tug.org/texlive/LICENSE.TL";
}
print("License:\t$license\n");
print("Source0:\thttp://mirrors.ctan.org/systems/texlive/tlnet/archive/$name.tar.xz\n");
if ($tlpobjdoc) {
    print("Source1:\thttp://mirrors.ctan.org/systems/texlive/tlnet/archive/$name.doc.tar.xz\n");
}
if ($tlpobjsrc) {
    if ($tlpobjdoc) {
	print("Source2");
    }
    else {
	print("Source1");
    }
    print(":\thttp://mirrors.ctan.org/systems/texlive/tlnet/archive/$name.source.tar.xz\n");
}
print("BuildArch:\tnoarch\n");
print("BuildRequires:\ttexlive-tlpkg\n");
print("Requires(pre):\ttexlive-tlpkg\n");

my $man1pages = 0;
my $man5pages = 0;
my $infopages = 0;

########################################################################
sub file_list {
    my ($doc, @list) = @_;
    foreach (@list) {
	if (m|/usr/share/texmf|) {
	    $_ =~ s|^/usr/share/texmf-dist|%{_texmfdistdir}|;
	    $_ =~ s|^/usr/share/texmf|%{_texmfdir}|;
	}
	elsif (m|^texmf|) {
	    $_ =~ s|^texmf-dist|%{_texmfdistdir}|;
	    $_ =~ s|^texmf|%{_texmfdir}|;
	}
	elsif (m|^RELOC|) {
	    $_ =~ s|^RELOC|%{_texmfdistdir}|;
	}
	else {
	    s/bin\/(x86_64|i386)-linux/\/usr\/bin/;
	    $_ = "%{_datadir}/$_" unless (m|^/|);
	}
	# Update for moved files or use macro
	if (/\.info$/) {
	    s/%{_texmf(dist)?dir}\/doc\/info\/(.*)\.info/%{_infodir}\/$2\.info\*/;
	    $infopages = 1;
	}
	if (/man\/man1/) {
	    $man1pages = 1;
	}
	if (/man\/man5/) {
	    $man5pages = 1;
	}
	if ($man1pages || $man5pages) {
	    s/%{_texmf(dist)?dir}\/doc\/man\/(man[15]\/.*\.[15]$)/%{_mandir}\/$2\*/;
	}
	s/\/usr\/bin/%{_bindir}/;
	s/\/usr\/share/%{_datadir}/;
	my $prefix = $special{$_};
	if ($prefix) {
	    print("$prefix$doc$_\n");
	}
	else {
	    print("$doc$_\n");
	}
    }
}

sub should_skip {
    my ($package) = @_;
    return 1 if (!$enable_asymptote && $package =~ /^asymptote/);
    return 1 if (!$enable_xindy && $package =~ /^xindy/);
    return 1 if ($with_system_lcdf && $package =~ /^lcdftypetools/);
    return 1 if ($with_system_psutils &&
		 ($package =~ /^psutils/ ||
		  $package =~ /^getafm/));
    return 1 if ($with_system_t1lib &&
		 $package =~ /^t1utils/);
    return 1 if ($package =~ /texworks/ ||
		 $package eq "texlive-msg-translations" ||
		 $package =~ /wintools/);
    return 1 if ($package =~ m/00texlive\./ ||
		 $package =~ m/texlive.infra/);
    return 0;
}

########################################################################
my @updmap = $tlpobj->updmap_cfg_lines();
my @fmtutil = grep(/^[^#]/, $tlpobj->fmtutil_cnf_lines());
my @datlines = $tlpobj->language_dat_lines();
for (my $i = 0; $i <= $#datlines; ++$i) {
    $datlines[$i] =~ s/%/%%/g;
    $datlines[$i] =~ s/(\$\\)/\\$1/g;
}
my @deflines = $tlpobj->language_def_lines();
for (my $i = 0; $i <= $#deflines; ++$i) {
    $deflines[$i] =~ s/%/%%/g;
    $deflines[$i] =~ s/(\$\\)/\\$1/g;
}
my @lualines = $tlpobj->language_lua_lines();

my $needs_post = 0;
my $mktexlsr = 0;
if (!$binary) {
    $needs_post = $name =~ /context/;
    my @runfiles = $tlpobj->runfiles();
    $mktexlsr = 1 if (grep(/texmf-dist|RELOC/, @runfiles));
    if (!$mktexlsr) {
	$mktexlsr = 1 if (grep(/texmf\//, @runfiles));
    }
}
if (!$needs_post) {
    $needs_post = ($mktexlsr ||
		   $#updmap > 0 || $#fmtutil > 0 ||
		   $#datlines > 0 || $#deflines > 0 || $#lualines > 0);
}
my %required;
if ($mktexlsr) {
    print("Requires(post):\ttexlive-kpathsea\n");
    $required{'kpathsea'} = 1;
    $required{'kpathsea.ARCH'} = 1;
}
if ($name ne "tetex" && ($#updmap > 0 || $#fmtutil > 0)) {
    print("Requires(post):\ttexlive-tetex\n");
    $required{'tetex'} = 1;
    $required{'tetex.ARCH'} = 1;
}
if ($name ne "hyphen-base" &&
    ($#datlines > 0 || $#deflines > 0 || $#lualines > 0)) {
    print("Requires(post):\ttexlive-hyphen-base\n");
    $required{'hyphen-base'} = 1;
}
if (!$binary && $name =~ /context/ && $name ne "context") {
    print("Requires(post):\ttexlive-context\n");
    $required{'contex'} = 1;
    $required{'contex.ARCH'} = 1;
}

foreach my $requires ($tlpobj->depends()) {
    next if ($name eq $requires || $required{$requires});
    if (should_skip($requires)) {
	if (defined($Requires{$requires})) {
	    print("Requires:\t" . $Requires{$requires} . "\n");
	}
	next;
    }
    if ($requires =~ m/^(.*)\.ARCH$/) {
	my $depends = "$1";
	print("Requires:\ttexlive-$depends.bin\n");
    }
    else {
	print("Requires:\ttexlive-$requires\n");
    }
}
if ($Provides{$name}) {
    foreach (split(", ", $Provides{$name})) {
	print("Provides:\t$_\n");
    }
}
if ($Obsoletes{$name}) {
    foreach (split(", ", $Obsoletes{$name})) {
	print("Obsoletes:\t$_\n");
	print("Conflicts:\t$_\n");
    }
}

# Ugly to add to every package, but otherwise urpmi may fail on upgrades
if ($binary) {
    print("Conflicts:\ttexlive <= 20110705-6\n");
}
else {
    print("Conflicts:\ttexlive-texmf <= 20110705-3\n");
    if ($tlpobjdoc) {
	my @doc = $tlpobjdoc->docfiles();
	if ($#doc > 0) {
	    print("Conflicts:\ttexlive-doc <= 20110705-3\n");
	}
    }
    if ($tlpobjsrc) {
	my @src = $tlpobjsrc->srcfiles();
	if ($#src > 0) {
	    print("Conflicts:\ttexlive-source <= 20110705-3\n");
	}
    }
}

my $description = $tlpobj->{'longdesc'};
if (!defined($description) || $description eq "") {
    $description = "TeXLive $name package.";
}
else {
    $description .= "." unless ($description =~ m/\.$/);
    $description =~ s/\b$arch\b/binary/g;
}
print("\n%description\n");
$_tmp = $description;
write;		# use that multilineformat

#--- pre/post
if ($needs_post) {
    print("\n%pre\n");
    print("    %_texmf_fmtutil_pre\n")		if ($#fmtutil > 0);
    print("    %_texmf_updmap_pre\n")		if ($#updmap > 0);
    print("    %_texmf_language_dat_pre\n")	if ($#datlines > 0);
    print("    %_texmf_language_def_pre\n")	if ($#deflines > 0);
    print("    %_texmf_language_lua_pre\n")	if ($#lualines > 0);
    if (!$binary && $name =~ /context/) {
	print("    %_texmf_mtxrun_pre\n");
    }
    print("    %_texmf_mktexlsr_pre\n")		if ($mktexlsr);
    print("\n%post\n");
    print("    %_texmf_mktexlsr_post\n")	if ($mktexlsr);
    print("    %_texmf_fmtutil_post\n")		if ($#fmtutil > 0);
    print("    %_texmf_updmap_post\n")		if ($#updmap > 0);
    print("    %_texmf_language_dat_post\n")	if ($#datlines > 0);
    print("    %_texmf_language_def_post\n")	if ($#deflines > 0);
    print("    %_texmf_language_lua_post\n")	if ($#lualines > 0);
    if (!$binary && $name =~ /context/) {
	print("    %_texmf_mtxrun_post\n");
    }
    print("\n%preun\n");
    print("    if [ \$1 -eq 0 ]; then\n");
    print("\t%_texmf_fmtutil_pre\n")		if ($#fmtutil > 0);
    print("\t%_texmf_updmap_pre\n")		if ($#updmap > 0);
    print("\t%_texmf_language_dat_pre\n")	if ($#datlines > 0);
    print("\t%_texmf_language_def_pre\n")	if ($#deflines > 0);
    print("\t%_texmf_language_lua_pre\n")	if ($#lualines > 0);
    if (!$binary && $name =~ /context/) {
	print("\t%_texmf_mtxrun_pre\n");
    }
    print("\t%_texmf_mktexlsr_pre\n")		if ($mktexlsr);
    print("    fi\n");
    print("\n%postun\n");
    print("    if [ \$1 -eq 0 ]; then\n");
    print("\t%_texmf_mktexlsr_post\n")		if ($mktexlsr);
    print("\t%_texmf_fmtutil_post\n")		if ($#fmtutil > 0);
    print("\t%_texmf_updmap_post\n")		if ($#updmap > 0);
    print("\t%_texmf_language_dat_post\n")	if ($#datlines > 0);
    print("\t%_texmf_language_def_post\n")	if ($#deflines > 0);
    print("\t%_texmf_language_lua_post\n")	if ($#lualines > 0);
    if (!$binary && $name =~ /context/) {
	print("\t%_texmf_mtxrun_post\n");
    }
    print("    fi\n");
}

print("\n#-----------------------------------------------------------------------");
print("\n%files\n");
file_list("", @{$tlpobj->{'binfiles'}{$arch}});
file_list("", $tlpobj->runfiles());
if ($name eq "tex4ht") {
    print("%{_javadir}/tex4ht.jar\n");
}
elsif ($name eq "xdvi") {
    print("%{_datadir}/X11/app-defaults/*\n");
}
elsif ($name eq "kpathsea.bin") {
    print("%{_sbindir}/mktexlsr.post\n");
}
if ($needs_post) {
    print("%_texmf_fmtutil_d/$name\n")		if ($#fmtutil > 0);
    print("%_texmf_updmap_d/$name\n")		if ($#updmap > 0);
    print("%_texmf_language_dat_d/$name\n")	if ($#datlines > 0);
    print("%_texmf_language_def_d/$name\n")	if ($#deflines > 0);
    print("%_texmf_language_lua_d/$name\n")	if ($#lualines > 0);
}
if ($tlpobjdoc) {
    file_list("%doc ", $tlpobjdoc->docfiles());
}
if ($tlpobjsrc) {
    print("#- source\n");
    file_list("%doc ", $tlpobjsrc->srcfiles());
}
print("%doc %{_tlpkgobjdir}/*.tlpobj\n");

print("\n#-----------------------------------------------------------------------");
print("\n%prep\n");
print("%setup -c -a0");
if ($tlpobjdoc && $tlpobjsrc) {
    print(" -a1 -a2");
}
elsif ($tlpobjdoc || $tlpobjsrc) {
    print(" -a1");
}
print("\n");
print("\n%build\n\n%install\n");
my $cp = "";
if ($relocated) {
    if (grep(/RELOC\/dvips\//, $tlpobj->runfiles())) {
	$cp = "$cp dvips";
    }
    if (grep(/RELOC\/bibtex\//, $tlpobj->runfiles())) {
	$cp = "$cp bibtex";
    }
    if (grep(/RELOC\/fonts\//, $tlpobj->runfiles())) {
	$cp = "$cp fonts";
    }
    if (grep(/RELOC\/omega\//, $tlpobj->runfiles())) {
	$cp = "$cp omega";
    }
    if (grep(/RELOC\/makeindex\//, $tlpobj->runfiles())) {
	$cp = "$cp makeindex";
    }
    if (grep(/RELOC\/metafont\//, $tlpobj->runfiles())) {
	$cp = "$cp metafont";
    }
    if (grep(/RELOC\/metapost\//, $tlpobj->runfiles())) {
	$cp = "$cp metapost";
    }
    if (grep(/RELOC\/scripts\//, $tlpobj->runfiles())) {
	$cp = "$cp scripts";
    }
    if ($mktexlsr && grep(/RELOC\/tex\//, $tlpobj->runfiles())) {
	$cp = "$cp tex";
    }
    if ($tlpobjdoc) {
	$cp = "$cp doc";
    }
    if ($tlpobjsrc) {
	$cp = "$cp source";
    }
    if ($cp ne "") {
	print("mkdir -p %{buildroot}%{_texmfdistdir}\n");
	print("cp -fpar$cp %{buildroot}%{_texmfdistdir}\n");
    }
}
else {
    if (grep(/texmf\//, $tlpobj->runfiles()) ||
	($tlpobjdoc && grep(/texmf\//, $tlpobjdoc->docfiles())) ||
	($tlpobjsrc && grep(/texmf\//, $tlpobjsrc->srcfiles()))) {
	$cp = "$cp texmf";
    }
    if (grep(/texmf-dist\//, $tlpobj->runfiles()) ||
	($tlpobjdoc && grep(/texmf-dist\//, $tlpobjdoc->docfiles())) ||
	($tlpobjsrc && grep(/texmf-dist\//, $tlpobjsrc->srcfiles()))) {
	$cp = "$cp texmf-dist";
    }
    if ($cp ne "") {
	print("mkdir -p %{buildroot}%{_datadir}\n");
	print("cp -fpar$cp %{buildroot}%{_datadir}\n");
    }
}
if ($man1pages) {
    print("mkdir -p %{buildroot}%{_mandir}/man1\n");
    print("mv %{buildroot}%{_texmfdir}/doc/man/man1/*.1 %{buildroot}%{_mandir}/man1\n");
}
if ($man5pages) {
    print("mkdir -p %{buildroot}%{_mandir}/man5\n");
    print("mv %{buildroot}%{_texmfdir}/doc/man/man5/*.5 %{buildroot}%{_mandir}/man5\n");
}
if ($infopages) {
    print("mkdir -p %{buildroot}%{_infodir}\n");
    print("mv %{buildroot}%{_texmfdir}/doc/info/*.info %{buildroot}%{_infodir}\n");
}
print("mkdir -p %{buildroot}%{_tlpkgobjdir}\n");
print("cp -fpa tlpkg/tlpobj/*.tlpobj %{buildroot}%{_tlpkgobjdir}\n");

#--- post
if ($needs_post) {
    if ($#fmtutil > 0) {
	print("mkdir -p %{buildroot}%{_texmf_fmtutil_d}\n");
	print("cat > %{buildroot}%{_texmf_fmtutil_d}/$name <<EOF\n");
	print(join("", @fmtutil));
	print("EOF\n");
    }
    if ($#updmap > 0) {
	print("mkdir -p %{buildroot}%{_texmf_updmap_d}\n");
	print("cat > %{buildroot}%{_texmf_updmap_d}/$name <<EOF\n");
	print(join("", @updmap));
	print("EOF\n");
    }
    if ($#datlines > 0) {
	print("mkdir -p %{buildroot}%{_texmf_language_dat_d}\n");
	print("cat > %{buildroot}%{_texmf_language_dat_d}/$name <<EOF\n");
	print(join("", @datlines));
	print("EOF\n");
    }
    if ($#deflines > 0) {
	print("mkdir -p %{buildroot}%{_texmf_language_def_d}\n");
	print("cat > %{buildroot}%{_texmf_language_def_d}/$name <<EOF\n");
	print(join("", @deflines));
	print("EOF\n");
    }
    if ($#lualines > 0) {
	print("mkdir -p %{buildroot}%{_texmf_language_lua_d}\n");
	print("cat > %{buildroot}%{_texmf_language_lua_d}/$name <<EOF\n");
	print(join("", @lualines));
	print("EOF\n");
    }
}

format multilineformat =
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
$_tmp
.
