#! /usr/bin/gap -q
# Copyright 2014 Bill Allombert <ballombe@debian.org>
# This program is distributed under the term of the GNU GPL2+
# The author assert no copyright interest in the output.

# require htmltotext

debhelperver := "9";

StandardsVersion := "4.1.3";

Commas:=function(list)
  return JoinStringsWithSeparator(list,", ");
end;

BaseDir:= function (path)
  local tmp, file, dir, name, ext;
  tmp :=  SplitString(path,"/");
  file:= tmp[Length(tmp)];
  Remove(tmp);
  dir := JoinStringsWithSeparator(tmp,"/");
  tmp := SplitString(file,".");
  ext := tmp[Length(tmp)];
  name := JoinStringsWithSeparator(tmp,".");
  return [dir, name, ext];
end;

Backquote:= function (prg)
  local shell, out, str;
  str := "";
  out := OutputTextString(str,true);
  Process( DirectoryCurrent(), "/bin/sh", InputTextNone(), out, ["-c", prg] );
  CloseStream(out);
  return Chomp(str);
end;

HTMLToText:=function(html)
  local shell, inp, out, str;
  str := "";
  inp := InputTextString(html);
  out := OutputTextString(str,true);
  Process(DirectoryCurrent(), "/usr/bin/html2text", inp, out,["-width","77"]);
  CloseStream(inp);
  CloseStream(out);
  return str;
end;

Email:=function(r)
  if IsBound(r.Email) then
    return Concatenation(" <",r.Email,">");
  else
    return "";
  fi;
end;

PkgName:=function(x)
  return Concatenation("gap-pkg-",LowercaseString(x));
end;

MakeDocBase:=function(binname, authors, abstract, pkgbase, Doc)
  local PackageDoc, PackageDocHTML, docid;
  PackageDoc := BaseDir(Doc.HTMLStart);
  PackageDocHTML := Concatenation(PackageDoc[1],"/*.",PackageDoc[3]);
  docid := LowercaseString(ReplacedString(Doc.BookName," ","-"));
  FileString(Concatenation("debian.gap2deb/",binname,".doc-base.",docid),Concatenation(
  "Document: gap-",docid,"\n",
  "Title: ",Doc.LongTitle,"\n",
  "Author: ",authors,"\n",
  "Abstract:\n ",abstract,"\n",
  "Section: Science/Mathematics\n",
  "\n",
  "Format: pdf\n",
  "Files: ",pkgbase,"/",Doc.PDFFile,"\n",
  "\n",
  "Format: HTML\n",
  "Index: ",pkgbase,"/",Doc.HTMLStart,"\n",
  "Files: ",pkgbase,"/",PackageDocHTML,"\n"));
end;

FatalError:=function(msg)
  local stderr;
  stderr:=OutputTextFile("*errout*",true);
  WriteAll(stderr, Concatenation(
    "GAP pkg to source Debian package converter\n",msg));
  CloseStream(stderr);
end;

if IsDirectoryPath("debian.gap2deb") then
  FatalError("debian.gap2deb directory already exists\n");
  quit;
fi;

if not IsReadableFile("PackageInfo.g") then
  FatalError(Concatenation(
"file PackageInfo.g not found\n",
"gap2deb must be launched inside a GAP package source directory\n"));
  quit;
fi;
Unbind( GAPInfo.PackageInfoCurrent );
Read("PackageInfo.g");
pkg:= GAPInfo.PackageInfoCurrent;
Unbind( GAPInfo.PackageInfoCurrent );

env:=GAPInfo.KernelInfo.ENVIRONMENT;
if IsBound(env.DEBFULLNAME) then
  maint := env.DEBFULLNAME;
else
  debemail:= env.DEBEMAIL;
  maintname:=SplitString(Backquote("getent passwd $USER"),":,")[5];
  maint:=Concatenation(maintname," <",debemail,">");
fi;

pkgname := LowercaseString(pkg.PackageName);
srcname := Concatenation("gap-",pkgname);
binname := Concatenation("gap-",pkgname);
synopsis := Concatenation("GAP ",pkg.PackageName," - ",pkg.Subtitle);
baseURL := "https://www.gap-system.org/pub/gap/gap4/tar.bz2/packages";
homepage := Concatenation("http://www.gap-system.org/Packages/",pkgname,".html");
date := Backquote("date -R");
year := Backquote("date +%Y");
copyyear := SplitString(pkg.Date,"/")[3];
abstract :=JoinStringsWithSeparator(SplitString(HTMLToText(pkg.AbstractHTML),"\n"),"\n ");
comp :=  SplitString(pkg.ArchiveURL,"/");
archivebase := SplitString(comp[Length(comp)],"0123456789")[1];
authors := Commas(List(pkg.Persons,x->Concatenation(x.FirstNames," ",x.LastName)));
authoremails :=
  Commas(List(pkg.Persons,x->Concatenation(x.FirstNames," ",x.LastName,Email(x))));
pkgbaseN:=Concatenation("usr/share/gap/pkg/",pkg.PackageName);
pkgbase:=Concatenation("/",pkgbaseN);

gapdepver :=  ReplacedString(pkg.Dependencies.GAP,".","r");
gapdep := Concatenation("gap (",gapdepver,")");
neededslist:=List(pkg.Dependencies.NeededOtherPackages,x->PkgName(x[1]));
suggestionslist := List(pkg.Dependencies.SuggestedOtherPackages,x->PkgName(x[1]));
conditionslist := List(pkg.Dependencies.ExternalConditions,x->x[1]);
Doc := pkg.PackageDoc;
if not IsList(Doc) then
  Doc := [ Doc ];
fi;
Depends:=Concatenation("Depends: ",
  Commas(Concatenation(["${misc:Depends}", gapdep],neededslist,conditionslist)),"\n");
if IsEmpty(suggestionslist) then
  Suggests:="";
else
  Suggests:=Concatenation("Suggests: ",Commas(suggestionslist),"\n");
fi;

CreateDir("debian.gap2deb");
CreateDir("debian.gap2deb/source");
CreateDir("debian.gap2deb/patches");
FileString("debian.gap2deb/source/format","3.0 (quilt)\n");

FileString("debian.gap2deb/compat",Concatenation(debhelperver,"\n"));

FileString("debian.gap2deb/changelog",Concatenation(
srcname," (",pkg.Version,"-1) unstable; urgency=low\n",
"\n",
"  * Initial Release.\n",
"  * This is part of the GAP system.\n",
"\n",
" -- ",maint,"  ",date,"\n"));

FileString("debian.gap2deb/control",Concatenation(
"Source: ",srcname,"\n",
"Section: math\n",
"Priority: optional\n",
"Maintainer: ",maint,"\n",
"Build-Depends: debhelper (>= ",debhelperver,"), gap (>= 4r7)\n",
"Standards-Version: ",StandardsVersion,"\n",
"Homepage: ",homepage,"\n",
"\n",
"Package: ",binname,"\n",
"Provides: gap-pkg-",pkgname,"\n",
Depends,
Suggests,
"Architecture: all\n",
"Description: ",synopsis,"\n",
" GAP is a system for computational discrete algebra, with particular emphasis\n",
" on Computational Group Theory. GAP provides a programming language, a library\n",
" of thousands of functions implementing algebraic algorithms written in the GAP\n",
" language as well as large data libraries of algebraic objects. GAP is used in\n",
" research and teaching for studying groups and their representations, rings,\n",
" vector spaces, algebras, combinatorial structures, and more.\n",
" .\n",
" ",pkg.Subtitle,"\n"));

FileString("debian.gap2deb/watch",Concatenation(
"version=3\n",
"opts=passive ",
baseURL,"/",archivebase,"([0-9].*)\\.tar\\.bz2 debian uupdate\n"));

for doc in Doc do
  MakeDocBase(binname, authors, abstract, pkgbase, doc);
od;

FileString("debian.gap2deb/copyright", Concatenation(
"Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\n",
"Upstream-Name: ",pkg.PackageName,"\n",
"Source: ",baseURL,"\n",
"\n",
"Files: *\n",
"Copyright: Copyright ",copyyear," ",authoremails,"\n",
"License: GPL-2+\n",
"\n",
"Files: debian/*\n",
"Copyright: Copyright ",year," ",maint,"\n",
"License: GPL-2+\n",
"\n",
"License: GPL-2+\n",
" This program is free software: you can redistribute it and/or modify\n",
" it under the terms of the GNU General Public License as published by\n",
" the Free Software Foundation, either version 2 of the license, or\n",
" (at your option) any later version.\n",
" .\n",
" This program is distributed in the hope that it will be useful,\n",
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n",
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n",
" GNU General Public License for more details.\n",
" .\n",
" You should have received a copy of the GNU General Public License\n",
" along with this program. If not, see <http://www.gnu.org/licenses/>.\n",
" .\n",
" On Debian systems, the full text of the GNU General Public\n",
" License version 2 can be found in the file\n",
" `/usr/share/common-licenses/GPL-2'.\n"));

FileString("debian.gap2deb/links", Concatenation(
  List(Doc,doc->Concatenation(pkgbase,"/",doc.ArchiveURLSubset[1]," /usr/share/doc/",binname,"/",doc.ArchiveURLSubset[1],"\n"))));

FileString("debian.gap2deb/patches/series", "doc-makefile\n");
FileString("debian.gap2deb/patches/doc-makefile", Concatenation(
"Index: ",srcname,"/doc/Makefile\n",
"===================================================================\n",
"--- /dev/null   1970-01-01 00:00:00.000000000 +0000\n",
"+++ ",srcname,"/doc/Makefile      2013-07-27 23:11:04.365369025 +0200\n",
"@@ -0,0 +1,36 @@\n",
"+SHELL=/bin/bash\n",
"+pkgdocdir=",pkgbase,"/doc\n",
"+DOCDIR=$(DESTDIR)$(pkgdocdir)\n",
"+MANUAL=main\n",
"+DIRS=.\n",
"+doc:\n",
"+\t./make_doc\n",
"+clean:\n",
"+\trm -f $(DIRS)/*.{html,txt,css,js}\n",
"+\trm -f $(DIRS)/make_manuals.out $(DIRS)/mathjax\n",
"+\trm -f $(DIRS)/$(MANUAL).{aux,bbl,blg,brf,idx,ilg,ind,log,out,pnr,tex,toc,toc.gz}\n",
"+\trm -f $(DIRS)/manual{,-bw}.{lab,six,six.gz,pdf}\n",
"+\trm -f manualbib.xml.bib\n",
"+install: install-pdf install-help install-html\n",
"+install-pdf:\n",
"+\ttest -d $(DOCDIR)/$(DIRS) || install -d $(DOCDIR)/$(DIRS)\n",
"+\tset -e; for man in $(DIRS); do \\\n",
"+\t  install -o root -g root -m 0644 $$man/manual.pdf $(DOCDIR)/$$man;\\\n",
"+\tdone\n",
"+install-help:\n",
"+\ttest -d $(DOCDIR)/$(DIRS) || install -d $(DOCDIR)/$(DIRS)\n",
"+\tset -e; for man in $(DIRS); do \\\n",
"+\t  gzip --best --no-name $$man/manual.six; \\\n",
"+\t  gzip --best --no-name $$man/$(MANUAL).toc; \\\n",
"+\t  install -o root -g root -m 0644 $$man/$(MANUAL)bib.xml $(DOCDIR)/$$man; \\\n",
"+\t  install -o root -g root -m 0644 $$man/$(MANUAL)bib.xml.bib $(DOCDIR)/$$man; \\\n",
"+\t  install -o root -g root -m 0644 $$man/$(MANUAL).toc.gz $(DOCDIR)/$$man; \\\n",
"+\t  install -o root -g root -m 0644 $$man/manual.six.gz $(DOCDIR)/$$man; \\\n",
"+\t  install -o root -g root -m 0644 $$man/*.txt $(DOCDIR)/$$man; \\\n",
"+\tdone\n",
"+install-html:\n",
"+\ttest -d $(DOCDIR)/$(DIRS) || install -d $(DOCDIR)/$(DIRS)\n",
"+\tset -e; for man in $(DIRS); do \\\n",
"+\t  install -o root -g root -m 0644 $$man/*.{html,css,js} $(DOCDIR)/$$man;\\\n",
"+\t  ln -s `readlink mathjax` $(DOCDIR)/$$man/mathjax;\\\n",
"+\tdone\n"));


testfile:=false;
if IsReadableFile("tst/testinstall.g") then
  testfile:="tst/testinstall.g";
elif IsReadableFile("tst/testall.g") then
  testfile:="tst/testall.g";
fi;

if testfile = false then
  dotest:="";
  cleantest:="";
else
  dotest:= Concatenation(
"ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))\n",
"\tmkdir -p debian/gaproot/pkg\n",
"\tln -s ../../.. debian/gaproot/pkg/",pkg.PackageName,"\n",
"\tgap -q -l 'debian/gaproot;/usr/share/gap' < ",testfile," | tee debian/gap.tst\n",
"endif\n");
  cleantest:=Concatenation(
"\trm -rf debian/gaproot\n",
"\trm -f debian/gap.tst\n");
fi;

FileString("debian.gap2deb/rules", Concatenation(
"#!/usr/bin/make -f\n",
"# Copyright ",year," ",maint,"\n",
"\n",
"build-indep-stamp:\n",
dotest,
"\tmake -C doc && touch build-indep-stamp\n",
"build-indep: build-indep-stamp\n",
"build-arch:\n",
"build: build-indep\n",
"\n",
"clean:\n",
"\tdh_testdir\n",
"\tdh_testroot\n",
"\tmake -C doc clean\n",
"\trm -f build-indep-stamp\n",
cleantest,
"\tdh_clean\n",
"\n",
"install: build\n",
"\tdh_testdir\n",
"\tdh_testroot\n",
"\tdh_prep\n",
"\tdh_installdirs\n",
"\tdh_install -X GPL -X README -X CHANGES -X -stamp -X debian -X tst -X doc -X htm -X.pc . ",
              pkgbaseN,"\n",
"\tmake -C doc install DESTDIR=../debian/",binname,"\n",
"binary-arch: build-arch\n",
"binary-indep: build-indep install\n",
"\tdh_testdir\n",
"\tdh_testroot\n",
"\tdh_installdocs README\n",
"\tdh_installexamples\n",
"\tdh_installchangelogs CHANGES\n",
"\tdh_link\n",
"\tdh_compress\n",
"\tdh_fixperms\n",
"\tdh_installdeb\n",
"\tdh_gencontrol\n",
"\tdh_md5sums\n",
"\tdh_builddeb\n",
"\n",
"binary: binary-indep binary-arch\n",
".PHONY: build clean binary-indep binary-arch binary install configure\n"));

if not IsDirectoryPath("debian") then
  Process(DirectoryCurrent(), "/bin/mv", InputTextNone(), OutputTextNone(),
          ["debian.gap2deb","debian"]);
fi;

QUIT;
