#!/usr/bin/perl

use strict;
use warnings;
use Debian::Copyright;
use Debian::PkgJs::Lib;
use Debian::PkgJs::Npm;
use Debian::PkgJs::Version;
use File::Basename qw(basename);
use POSIX qw(strftime);

my $basename = basename($0);

sub usage {
    print <<EOF;
Usage: $basename

$basename prepares a debian/ directory by reading package.json of a node package.

Launch it in a debian/node source repository.

Copyright (C) 2019 Andrius Merkys <merkys\@debian.org>

Licensed under GPL-2+ (see /usr/share/common-licenses/GPL-2)
EOF
}

if (@ARGV) {
    if ( $ARGV[0] eq '--version' ) {
        print $VERSION, "\n";
    }
    else {
        usage();
    }
    exit;
}

my $package = pjson('.') || die "$basename: no 'package.json'";

my $name        = $package->{name};
my $source      = "node-$name";
my $version     = $package->{version};
my $license     = $package->{license};
my $author      = $package->{author};
my $description = $package->{description};
my $homepage    = $package->{homepage};
my $test        = $package->{scripts}{test};

my $debfullname = $ENV{DEBFULLNAME};
my $debemail    = $ENV{DEBEMAIL};

my $date = strftime( "%a, %d %b %Y %H:%M:%S %z", localtime( time() ) );

my $upstream_vcs_url;
my $upstream_vcs_type;
if ( $package->{repository} && ref $package->{repository} eq 'HASH' ) {
    $upstream_vcs_url  = $package->{repository}{url};
    $upstream_vcs_type = $package->{repository}{type};
}

# Using GitHub's anonymous HTTPS cloning URLs instead of git@github.com:
if ( $upstream_vcs_type && $upstream_vcs_type eq 'git' ) {
    $upstream_vcs_url =~ s|^git\@(github\.com):|https://$1/|;
    $upstream_vcs_url =~ s|\.git$||;
}

mkdir('debian');

my $out;

#-------------- debian/changelog -----------

if ( !-e 'debian/changelog' ) {
    system( 'dch', '--create', '--newversion', "$version-1",
        '--package', $source, 'Initial release (Closes: #nnnn)' );
}

#-------------- debian/rules ---------------

open( $out, '>', 'debian/rules' );
print $out <<END;
#!/usr/bin/make -f

%:
\tdh \$@ --buildsystem nodejs
END
close $out;
chmod 0755, 'debian/rules';

#-------------- debian/copyright -----------

my $copyright = Debian::Copyright->new();
my $header    = Debian::Copyright::Stanza::Header->new(
    {
        Disclaimer => 'Autogenerated by dh-make-node',
        Format     =>
          'https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/',
        Source             => $upstream_vcs_url,
        'Upstream-Contact' => $author,
        'Upstream-Name'    => $name,
    }
);
$copyright->header($header);

if ( !$license ) {
    warn "$basename: license information is not found in package.json\n";
}

$copyright->files->Push(
    '*',
    Debian::Copyright::Stanza::Files->new(
        {
            Files     => '*',
            Copyright => $author,
            License   => $license,
        }
    )
);

$copyright->files->Push(
    'debian/*',
    Debian::Copyright::Stanza::Files->new(
        {
            Files     => 'debian/*',
            Copyright => "$debfullname <$debemail>",
            License   => $license,
        }
    )
);

$copyright->licenses->Push(
    $license,
    Debian::Copyright::Stanza::License->new(
        {
            License => $license,
        }
    )
);

$copyright->write('debian/copyright');

#-------------- debian/control ---------------

my @dependencies = resolve_dependencies( $package->{dependencies} );
push @dependencies, resolve_dependencies( $package->{peerDependencies} );
my @devDependencies = resolve_dependencies( $package->{devDependencies} );

my @build_depends = (
    'debhelper-compat (= 12)',
    'pkg-js-tools', @dependencies, map { "$_ <!nocheck>" } @devDependencies
);

my @depends = ( '${misc:Depends}', @dependencies );

my $build_depends = join "\n", map { " $_," } sort @build_depends;
my $depends       = join "\n", map { " $_," } sort @depends;

my $homepage_line = 'Homepage: ';
if ($homepage) {
    $homepage_line .= $homepage;
}
else {
    $homepage_line = "#$homepage_line<insert URL if applicable>";
}

open( $out, '>', 'debian/control' );
print $out <<END;
Source: $source
Section: javascript
Priority: optional
Maintainer: Debian Javascript Maintainers <pkg-javascript-devel\@lists.alioth.debian.org>
Uploaders:
 $debfullname <$debemail>,
Build-Depends:
$build_depends
Standards-Version: 4.4.0
Rules-Requires-Root: no
$homepage_line
Vcs-Browser: https://salsa.debian.org/js-team/$source
Vcs-Git: https://salsa.debian.org/js-team/$source.git
END

print $out "Testsuite: autopkgtest-pkg-nodejs\n" if $test;

print $out <<END;

Package: $source
Architecture: all
Depends:
$depends
Description: $description
END
close $out;

#-------------- debian/watch -----------------

if (   $upstream_vcs_type
    && $upstream_vcs_type eq 'git'
    && $upstream_vcs_url =~ /github/ )
{
    open( $out, '>', 'debian/watch' );
    print $out "version=4\n";
    print $out git_watch($upstream_vcs_url);
    close $out;
}

#-------------- debian/source/format ---------

mkdir('debian/source');
open( $out, '>', 'debian/source/format' );
print $out "3.0 (quilt)\n";
close $out;

#------------ debian/tests/pkg-js/test ---------

if ($test) {
    mkdir('debian/tests');
    mkdir('debian/tests/pkg-js');

    # Using system-provided test runners:
    $test =~ s|^\./node_modules/\.bin/||;

    open( $out, '>', 'debian/tests/pkg-js/test' );
    print $out <<END;
#!/bin/bash

$test
END
    close $out;
}

sub resolve_dependencies {
    my ($dependencies) = @_;
    return () if !$dependencies;

    my @deb_dependencies;
    for my $dep ( sort keys %$dependencies ) {
        if ( $dep !~ /^[a-z0-9\-\.]+$/ ) {
            warn
              "$basename: dependency name '$dep' looks suspicious, skipping\n";
            next;
        }
        my $pkg = `nodepath -o $dep 2>/dev/null`;
        if ( !$pkg ) {
            warn
"$basename: dependency '$dep' cannot be found, is it installed?\n";
            next;
        }

        $pkg =~ s/\n$//;
        push @deb_dependencies, $pkg if $pkg;
    }

    return sort @deb_dependencies;
}
