<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

namespace local_unifiedgrader\pdf;

defined('MOODLE_INTERNAL') || die();

/**
 * Combines a feedback summary PDF with an annotated submission PDF.
 *
 * Uses GhostScript (via Moodle's $CFG->pathtogs) to merge PDFs. This is
 * necessary because the annotated PDFs are generated by pdf-lib (JavaScript)
 * which outputs PDF 1.7 with cross-reference streams — incompatible with the
 * FPDI Free library bundled with Moodle (which only handles PDF <= 1.4).
 *
 * GhostScript is already a Moodle system requirement for assignfeedback_editpdf.
 *
 * @package    local_unifiedgrader
 * @copyright  2026 South African Theological Seminary (mathieu@sats.ac.za) (https://www.sats.ac.za)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class combined_feedback_pdf {

    /**
     * Combine a summary PDF with an annotated PDF using GhostScript.
     *
     * The summary pages appear first, followed by all annotated PDF pages.
     *
     * @param string $summarypdfbytes Raw PDF bytes of the summary page(s)
     * @param string $annotatedpdfbytes Raw PDF bytes of the annotated submission
     * @return string Combined PDF as binary string
     * @throws \moodle_exception If GhostScript is not configured or the merge fails
     */
    public function combine(string $summarypdfbytes, string $annotatedpdfbytes): string {
        global $CFG;

        raise_memory_limit(MEMORY_EXTRA);

        // GhostScript path from Moodle config (same as used by assignfeedback_editpdf).
        $gspath = $CFG->pathtogs ?? '';
        if (empty($gspath) || !is_executable($gspath)) {
            throw new \moodle_exception('error_gs_not_configured', 'local_unifiedgrader');
        }

        $tempdir = make_request_directory();
        $summaryfile = $tempdir . '/summary.pdf';
        $annotatedfile = $tempdir . '/annotated.pdf';
        $outputfile = $tempdir . '/combined.pdf';

        file_put_contents($summaryfile, $summarypdfbytes);
        file_put_contents($annotatedfile, $annotatedpdfbytes);

        // Merge PDFs using GhostScript — same pattern as assignfeedback_editpdf.
        $gsexec = escapeshellarg($gspath);
        $outputarg = escapeshellarg($outputfile);
        $summaryarg = escapeshellarg($summaryfile);
        $annotatedarg = escapeshellarg($annotatedfile);

        $command = "$gsexec -q -sDEVICE=pdfwrite -dSAFER -dBATCH -dNOPAUSE "
            . "-dCompatibilityLevel=1.7 "
            . "-sOutputFile=$outputarg $summaryarg $annotatedarg 2>&1";

        $output = null;
        $returncode = null;
        exec($command, $output, $returncode);

        if ($returncode !== 0 || !file_exists($outputfile)) {
            $outputstr = implode("\n", $output ?? []);
            throw new \moodle_exception(
                'error_pdf_combine_failed',
                'local_unifiedgrader',
                '',
                $outputstr,
            );
        }

        $result = file_get_contents($outputfile);

        // Clean up temp files.
        @unlink($summaryfile);
        @unlink($annotatedfile);
        @unlink($outputfile);

        return $result;
    }
}
