# A debhelper build system class for building Pd-externals with pd-lib-builder.
#
# Copyright: © 2022 IOhannes m zmölnig
# License: GPL-2+

package Debian::Debhelper::Buildsystem::pd_lib_builder;

use strict;
use warnings;
use Debian::Debhelper::Dh_Lib qw(compat dpkg_architecture_value);
use Dpkg::Version qw();

use parent qw(Debian::Debhelper::Buildsystem::makefile);

sub DESCRIPTION {
    "pd-lib-builder based externals"
}

sub new {
    # pd-lib-builder does not allow out-of-tree building
    my $class=shift;
    my $this=$class->SUPER::new(@_);
    $this->enforce_in_source_building();
    return $this;
}

sub _should_inject_cross_build_tools {
    return 1;
}

sub check_auto_buildable {
    # pd-lib-builder can be enabled if there is a makefile
    # that calls 'include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder'
    my $this=shift;
    my ($step)=@_;
    foreach my $f ("Makefile", "makefile", "GNUmakefile") {
        my $f1 = $this->get_buildpath($f);
        if (! -e $f1) {
            next;
        }
        open (my $MAKEFILE, "<", $f1) || next;
        while (<$MAKEFILE>) {
            chomp;
            if (/^include \$\(PDLIBBUILDER_DIR\)\/Makefile\.pdlibbuilder/) {
                close $MAKEFILE;
                return ($this->SUPER::check_auto_buildable(@_)) + 1;
            }
        }
        close $MAKEFILE;
        return 0;
    }
    return 0;
}

sub check_can_double {
    open(my $MAKEFILE, "<", "/usr/share/pd-lib-builder/Makefile.pdlibbuilder");
    while (<$MAKEFILE>) {
        chomp;
        if (/^floatsize/) {
            close $MAKEFILE;
            return 1;
        }
    }
    close $MAKEFILE;
    return 0;
}

sub do_flavours {
    # only call if the first flavour succeeded (returns success of last called flavour)
    # > do_flavours($this, 0, "build", @_);
    # always call all flavours (returns success of first called flavour)
    # > do_flavours($this, 1, "clean", @_);
    my $this = shift;
    my $ignore_result = shift;
    my $fun = shift;
    $fun = "SUPER::$fun";

    # normal flavour
    my $result = $this->$fun(@_);

    my $can_double = check_can_double;
    if ($ENV{DEB_HOST_ARCH} eq "") {
        $can_double = 0;
    }
    # double flavour
    if ($can_double and ($result or $ignore_result)) {
        # calculate a proper value for a <cpu> part of the extension
        my $deb_host_arch = dpkg_architecture_value("DEB_HOST_ARCH");
        chomp (my $cpu=qx{/usr/share/puredata/debian/dekencpu ${deb_host_arch} 2>/dev/null});
        if ($cpu eq "") {
            # if there's none (e.g. because the helper script doesn't exist),
            # fall back to some default
            $cpu = ${deb_host_arch};
        }
        push(@_, "floatsize=64");
        push(@_, "extension=linux-${cpu}-64.so");
        my $r = $this->$fun(@_);
        if (not $ignore_result) {
            $result = $r;
        }
    }
    return $result;
}

sub clean {
    # use Debian's Makefile.pdlibbuilder by passing PDLIBBUILDER_DIR
    my $this=shift;
    unshift(@_, "PDLIBBUILDER_DIR=/usr/share/pd-lib-builder/");
    return do_flavours($this, 1, "clean", @_);
}

sub build {
    # use Debian's Makefile.pdlibbuilder by passing PDLIBBUILDER_DIR
    # also override CPPFLAGS, CFLAGS, LDFLAGS
    # and arch.c.flags (which contains optimization flags that exceed our baseline)
    my $this=shift;

    unshift(@_, "PDLIBBUILDER_DIR=/usr/share/pd-lib-builder/");
    unshift(@_, "CPPFLAGS=$ENV{CPPFLAGS}");
    unshift(@_, "CFLAGS=$ENV{CPPFLAGS} $ENV{CFLAGS}");
    unshift(@_, "LDFLAGS=$ENV{LDFLAGS}");
    unshift(@_, "arch.c.flags=");
    if (not compat(10)) {
        unshift @_, "INSTALL=install --strip-program=true";
    }
    return do_flavours($this, 0, "build", @_);
}

sub test {
    # use Debian's Makefile.pdlibbuilder by passing PDLIBBUILDER_DIR
    my $this=shift;
    unshift(@_, "PDLIBBUILDER_DIR=/usr/share/pd-lib-builder/");
    # for now we only run tests on 32bit Pd
    $this->SUPER::test(@_);
}

sub install {
    # use Debian's Makefile.pdlibbuilder by passing PDLIBBUILDER_DIR
    my $this=shift;
    my $destdir=shift;

    unshift(@_, "PDLIBBUILDER_DIR=/usr/share/pd-lib-builder/");
    unshift(@_, "prefix=/usr");
    unshift(@_, "pkglibdir=/usr/lib/pd/extra");
    if (not compat(10)) {
        unshift @_, "INSTALL=install --strip-program=true";
    }
    return do_flavours($this, 0, "install", $destdir, @_);
}

1;
