use Data::Dumper;
use IO::File;
use File::HomeDir ;
use strict;
use warnings;
use utf8;

$conf_file_name = "";
$conf_dir       = '';
$model_to_test  = "Dpkg";

eval { require AptPkg::Config; };
$skip = ( $@ or not -r '/etc/debian_version' ) ? 1 : 0;

# required to set value that enable creation of dummy changelog:
# changelog is computed from my_config email and name which are also
# computed from environment variable. If any of these var is undef,
# the my_config value are undef, and the changelog is also undef. In
# this case, the changalog file is not written and the tests that
# expect a new changelog file also fail.. Kind of domino effect
$ENV{DEBFULLNAME} ||= "John Doe";
$ENV{DEBEMAIL} ||= 'johndoe@naibed.gro';

my %add_map = (
    # Works also on Windows
    home => File::HomeDir->my_home."/.dpkg-meta.yml",
    log => '/debian/changelog',
    rules => '/debian/rules',
);

# used to tweak list of debian files
sub add {
    # @to_add is a closure used in inner sub
    my @to_add = @_;
    return sub {
        push @{$_[0]}, map { $add_map{$_} } @to_add;
    };
};

@tests = (
    {   name => 't0',
        check => {
            'control source Build-Depends-Indep:3' => 'libtest-pod-perl',
            'control source Build-Depends:0' => 'debhelper (>= 8)',
            'compat' => 8,
        },
        # add() returns a sub used to tweak file list
        file_check_sub => add('home'),
        apply_fix => 1 ,
        load_warnings => [ qr/dual life/ ],
    },
    {   name => 't1',
        load_warnings => [ qr/standard/, qr/compat/, (qr/canonical/) x 2 ],
        apply_fix => 1 ,
        load => qq!patches:fix-spelling Description="more spelling details"!
            . qq( ! patches:glib-single-include Synopsis="mega patchchoid")
            ,
        check => {
            'patches:fix-spelling Synopsis', 'fix man page spelling',
            # test synopsis generated from patch name
            'patches:fix-man-page-spelling Synopsis', 'Fix man page spelling',
            'patches:use-standard-dzil-test Synopsis', "use standard dzil test suite",
            'patches:glib-single-include Synopsis', "mega patchchoid",
            'patches:use-standard-dzil-test Description',
              "Test is modified in order not to load the Test:Dzil module\nprovided in t/lib",
            'compat' => 8 , # test setup
            'control source Build-Depends:0' => 'debhelper (>= 8)' ,
        },
        file_check_sub => add('home'),
        # dump_warnings => [ (qr/deprecated/) x 3 ],
    },

    {
        name => 'autopkgtest',
        check => {
            'tests control:0 Tests:0' => 'fred',
            'tests control:0 Tests:2' => 'bongo',
            'tests control:0 Depends' => "pkg1, pkg2 [amd64] | pkg3 (>= 3)",
            'tests control:0 Restrictions' => "breaks-testbed,needs-root",
        },
        # add() returns a sub used to tweak file list
        file_check_sub => add('home'),
        apply_fix => 1 ,
        load_warnings => [ qr/dual life/ ],
    },

    { 
        name => 'libversion' ,
        load_warnings => [ qr/standard/, qr/unnecessary/, (qr/dual life/) x2, (qr/canonical/) x 2 ],
        apply_fix => 1 ,
        check => {
            'control source Build-Depends-Indep:0' => 'perl',
            'control source Build-Depends-Indep:1' => 'perl (>= 5.9.5) | libversion-perl (>= 0.7203)',
            # check that duplicated dependency is removed
            'control source Build-Depends-Indep:2' => 'libdist-zilla-perl',
            'bugfiles:libversion bug-script' => qr/dummy script/,
            'bugfiles:libversion bug-control report-with' => 'libreoffice-core',
            'bugfiles:libversion bug-control package-status' => 'udev dracut initramfs-tools',
        },
        file_check_sub => add('home'),
    },
    {
        name => 'pan-copyright-from-scratch',
        update => { in => path('t/scanner/examples/pan.in'), quiet => 1, no_warnings => 0 },
        no_warnings => 1,
        check => {
            "copyright License:GPL-2 text" => {value => undef, mode => 'custom'},
            "copyright Upstream-Name" => 'pan',
            "copyright License:GPL-2 text" => qr/GNU/,

            # copyright from files or existing debian/copyright are now normalised
            'copyright Files:pan/general/sorted-vector.h Copyright' => '2002, Martin Holzherr (holzherr@infobrain.com).',

            # no space after comma because data comes from fix.scanned.copyright
            'copyright Files:pan/general/map-vector.h Copyright' => "2001,Andrei Alexandrescu",
            'copyright Files:pan/general/map-vector.h License short_name' => 'MIT',
            'copyright Files:pan/general/map-vector.h License full_license' => undef,
            'copyright Files:pan/general/sorted-vector.h Copyright' =>
            '2002, Martin Holzherr (holzherr@infobrain.com).'
        },
        wr_check => {
            "copyright License:GPL-2 text" => {value => undef, mode => 'custom'},
            "copyright License:GPL-2 text" => qr/GNU/,
        },
        file_check_sub => add(qw/home log/),
    },
    {
        # should that be pan-copyright-upgrate ? :-p
        name => 'pan-copyright-upgrade-update',
        update => { in => path('t/scanner/examples/pan.in'), quiet => 1 },
        no_warnings => 1,

        check => {
            "copyright License:GPL-2 text" => {value => undef, mode => 'custom'},
            "copyright License:GPL-2 text" => qr/GNU/,
            'copyright Files:pan/general/map-vector.h Copyright' => qr"2001, Andrei Alexandrescu",
            'copyright Files:pan/general/map-vector.h License short_name' => 'NTP',
            'copyright Files:pan/general/map-vector.h License full_license'
            => 'yada yada show-copyright stuff',
            'copyright Files:pan/general/sorted-vector.h Copyright'
            => '2002, Martin Holzherr (holzherr@infobrain.com).',
            'copyright Files:pan/general/sorted-vector.h License short_name' => 'public-domain',
            # entry "uulib/fptools.c\n uulib/fptools.h"is packed by update
            qq'copyright Files:"*" Copyright' => '1994-2001, Frank Pilhofer.',
            'copyright Files:pan/gui/xface.c Copyright' => qr/^James/,
        },
        wr_check => {
            "copyright License:GPL-2 text" => {value => undef, mode => 'custom'},
            "copyright License:GPL-2 text" => qr/GNU/,
        },
        file_check_sub => add(qw/home log/),
    },
    {
        # emulate removed and added file, updated copyright years
        # the difference with above test is in debian/copyright file to be updated
        name => 'pan-copyright-upgrade-update-more',
        update => { in => path('t/scanner/examples/pan.in'), quiet => 1 },
        no_warnings => 1,
        check => {
            "copyright License:GPL-2 text" => {value => undef, mode => 'custom'},
            "copyright License:GPL-2 text" => qr/GNU/,
            'copyright Files:pan/general/map-vector.h Copyright' => qr"2001, Andrei Alexandrescu",
            'copyright Files:pan/general/map-vector.h License short_name' => 'NTP',
            'copyright Files:pan/general/map-vector.h License full_license'
            => 'yada yada show-copyright stuff',
            'copyright Files:pan/general/sorted-vector.h Copyright'
            => '2002, Martin Holzherr (holzherr@infobrain.com).',
            'copyright Files:pan/general/sorted-vector.h License short_name' => 'public-domain',
            qq'copyright Files:"*" Copyright' => '1994-2001, Frank Pilhofer.',
        },
        has_key => {
            'copyright Files' => ['*'],
        },
        has_not_key => {
            'copyright Files' => ['pan/data/*','uulib/*'],
        },
        wr_check => {
            "copyright License:GPL-2 text" => {value => undef, mode => 'custom'},
            "copyright License:GPL-2 text" => qr/GNU/,
        },
        file_check_sub => add(qw/home log/),
    },

    {
        # Debian bug #795195
        name => 'open-nebula-from-scratch',
        update => { in => path('t/scanner/examples/open-nebula.in'), quiet => 1 },
        load => 'copyright License:"MPL-2.0" text="mpl 2.0 blah-blah € «»" '
            . '! copyright Files:"src/sunstone/public/css/novnc-custom.css" License full_license~',
        file_contents_like => {
            'debian/copyright' => [
                qr!Files: src/im_mad/remotes/az.d/\*!, '€ «»'
            ]
        },
        file_check_sub => add(qw/rules home log/),
        file_contents_unlike => {
            'debian/copyright' => [
                qr!Files: src/im_mad/\*!,
                qr!Files: share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/\*!,
                qr!Files: NOTICE!,
                qr!Files: debian!,
            ],
        },

    },

    {
        # Debian bug #795195
        name => 'open-nebula',
        update => {
            in => path('t/scanner/examples/open-nebula.in'),
            quiet => 1,
            # fill.copyright.blanks tests #863052. Unfortunately, the
            # only symptom is a warning showing up during upgrade,
            # hence this update_warnings which works only from
            # Config::Model::Tester 2.061 (ignored otherwise)
            update_warnings => []
        },
        file_contents_like => {
            'debian/copyright' => [
                qr!Files: src/im_mad/remotes/az.d/\*!
            ]
        },
        file_check_sub => add(qw/rules home log/),
        # check that some entries were fixed by update
        check => {
            'copyright Files:"share/vendor/*" Copyright' => '2010-2012, VMware, Inc.',
            'copyright Files:"src/sunstone/public/css/novnc-custom.css" Copyright' => qr/Mannehed/,
            'copyright Files:"src/cloud/ec2/lib/net_ssh_replacement.rb" Copyright' => qr/Jamis/,
            'copyright Files:"share/pkgs/openSUSE/systemd/onedsetup" Copyright' => '2015, Marcel Mézigue',
            'copyright Files:"share/pkgs/openSUSE/systemd/onedsetup" License short_name' => 'GPL-3+ or Apache-2.0, and unicode'

        },
        file_contents_unlike => {
            'debian/copyright' => [
                qr!Files: src/[hit]m_mad/\*!,
            ],
        },

    },

    {
        name => 'rakudo-star',
        update => { in => path('t/scanner/examples/rakudo-star.in'), quiet => 1 },
        no_warnings => 1,
        check => {
            'copyright Files:"modules/Perl6-MIME-Base64/*" Copyright' => 'Adrian White',
            'copyright Files:"modules/DBIish/*" Comment' => qr/should be preserved by cme update/,
            'install:rakudo-star list:0' => 'usr/bin/*',
            'install:rakudo-star list:1' => 'usr/share/*',
        },
        file_check_sub => add(qw/home log/),
    },

    {
        name => 'batmon-app',
        update => { in => path('t/scanner/examples/batmon.app.in'), quiet => 1 },
        no_warnings => 1,
        check => {
        },
        # this entry is merged in debian/* *if* the Copyright coming from file is normalised
        # Also closes #862368
        has_not_key => [
            'copyright Files' => 'GNUmakefile',
        ],
        file_check_sub => add(qw/home/),
        file_contents_unlike => {
            'debian/copyright' => [
                qr!Files: GNUmakefile!,
            ],
        },
    },

);

my $cache_file = 't/model_tests.d/dependency-cache.txt';

$Config::Model::Dpkg::Dependency::use_test_cache = 1;

my $ch = new IO::File "$cache_file";
foreach ( $ch->getlines ) {
    chomp;
    my ( $k, $v ) = split m/ => /;
    $Config::Model::Dpkg::Dependency::cache{$k} = time . ' '. $v;
}
$ch->close;

END {
    return if $::DebianDependencyCacheWritten;
    my %h = %Config::Model::Dpkg::Dependency::cache;
    map { s/^\d+ //;} values %h ; # remove time stamp
    my $str = join( "\n", map { "$_ => $h{$_}"; } sort keys %h );

    my $fh = new IO::File "> $cache_file";
    print "writing back cache file\n";
    if ( defined $fh ) {

        # not a big deal if cache cannot be written back
        $fh->print($str);
        $fh->close;
        $::DebianDependencyCacheWritten = 1;
    }
}

1;
