#!/usr/bin/env perl
require 5.008;
use warnings;
use strict;

unshift(@INC, '.');
require qpdf_test_helpers;

chdir("qpdf") or die "chdir testdir failed: $!\n";

require TestDriver;

cleanup();

my $td = new TestDriver('merge-and-split');

my $n_tests = 28;

# Select pages from the same file multiple times including selecting
# twice from an encrypted file and specifying the password only the
# first time.  The file 20-pages.pdf is specified with two different
# paths to duplicate a page.
my $pages_options = "--pages page-labels-and-outlines.pdf 1,3,5-7,z" .
    " 20-pages.pdf --password=user z-15" .
    " page-labels-and-outlines.pdf 12" .
    " 20-pages.pdf 10" .
    " ./20-pages.pdf --password=owner 10" .
    " minimal.pdf 1 --";

$td->runtest("merge three files",
             {$td->COMMAND => "qpdf page-labels-and-outlines.pdf a.pdf" .
                  " $pages_options --static-id --verbose --progress",
                  $td->FILTER => "perl filter-progress.pl"},
             {$td->FILE => "verbose-merge.out", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
# Manually verified about this file: make sure that outline entries
# that pointed to pages that were preserved still work in the copy,
# and verify that all pages are as expected.  page-labels-and-outlines
# as well as 20-pages have text on page n (from 1) that shows its page
# position from 0, so page 1 says it's page 0.
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "merge-three-files-1.pdf"});
# Select the same pages but add them to an empty file
$td->runtest("merge three files",
             {$td->COMMAND => "qpdf --empty a.pdf" .
                  " $pages_options --static-id"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
# Manually verified about this file: it has the same pages but does
# not contain outlines or other things from the original file.
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "merge-three-files-2.pdf"});
$td->runtest("avoid respecification of password",
             {$td->COMMAND =>
                  "qpdf --empty a.pdf --copy-encryption=20-pages.pdf" .
                  " --allow-weak-crypto" .
                  " --encryption-file-password=user" .
                  " --pages 20-pages.pdf 1,z -- --static-id"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "pages-copy-encryption.pdf"});
$td->runtest("merge with implicit ranges",
             {$td->COMMAND =>
                  "qpdf --empty a.pdf" .
                  " --pages minimal.pdf 20-pages.pdf --password=user" .
                  " page-labels-and-outlines.pdf --" .
                  " --static-id"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "merge-implicit-ranges.pdf"});
$td->runtest("merge with . and implicit ranges",
             {$td->COMMAND =>
                  "qpdf minimal.pdf a.pdf --pages minimal.pdf . 1 --" .
                  " --static-id"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "merge-dot-implicit-ranges.pdf"});
$td->runtest("merge with multiple labels",
             {$td->COMMAND =>
                  "qpdf --empty a.pdf" .
                  " --pages 11-pages-with-labels.pdf 8-11" .
                  " minimal.pdf " .
                  " page-labels-and-outlines.pdf 17-19 --" .
                  " --static-id"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "merge-multiple-labels.pdf"});
$td->runtest("remove labels",
             {$td->COMMAND =>
                  "qpdf --empty a.pdf" .
                  " --remove-page-labels" .
                  " --pages 11-pages-with-labels.pdf 8-11" .
                  " minimal.pdf " .
                  " page-labels-and-outlines.pdf 17-19 --" .
                  " --static-id"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "remove-labels.pdf"});

$td->runtest("split with shared resources",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id" .
                  " --remove-unreferenced-resources=yes" .
                  " shared-images.pdf --pages . 1,3" .
                  " ./shared-images.pdf 1,2 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "shared-images-pages-out.pdf"});

$td->runtest("split with really shared resources",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id" .
                  " --remove-unreferenced-resources=yes" .
                  " shared-images.pdf --pages . 1,3" .
                  " . 1,2 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "really-shared-images-pages-out.pdf"});

$td->runtest("shared resources relevant errors",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id" .
                  " shared-images-errors.pdf --pages . 2 -- a.pdf"},
             {$td->FILE => "shared-images-errors-2.out",
                  $td->EXIT_STATUS => 3},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "shared-images-errors-2-out.pdf"});

# This test used to generate warnings about images on pages we didn't
# care about, but qpdf was modified not to process those pages, so the
# "irrelevant" errors went away.
$td->runtest("shared resources irrelevant errors",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id" .
                  " shared-images-errors.pdf --pages . 1 -- a.pdf"},
             {$td->STRING => "",
                  $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "shared-images-errors-1-out.pdf"});

$td->runtest("don't remove shared resources",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id --preserve-unreferenced-resources" .
                  " shared-images.pdf --pages . 1,3 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "shared-images-errors-1-3-out.pdf"});

$td->runtest("duplicate pages",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id 11-pages-with-labels.pdf" .
                  " --pages . 6,5,6 . 5 minimal.pdf 1,1 minimal.pdf 1 --" .
                  " a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0});
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "duplicate-pages.pdf"});

# See https://github.com/qpdf/qpdf/issues/399 -- we don't want to
# break this, especially if we ever implement deduplication of
# identical streams.
$td->runtest("force full page duplication",
             {$td->COMMAND => "qpdf --static-id minimal.pdf" .
                  " --pages . ./minimal.pdf -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "deep-duplicate-pages.pdf"});


cleanup();
$td->report($n_tests);
