/*
 * Copyright (c) 1997-2026 IDRsolutions (https://www.idrsolutions.com)
 */
package org.jpedal.examples.handlers;

import org.jpedal.PdfDecoder;
import org.jpedal.examples.viewer.Viewer;
import org.jpedal.examples.viewer.ViewerCommands;
import org.jpedal.io.DefaultErrorTracker;

import java.io.File;


/**
 * Example showing how to monitor page decoding with an ErrorTracker. The tracker stops decoding any page that takes
 * longer than 1.5 seconds and reports it as timed out.
 */
public final class ExampleErrorTracker {

    /**
     * Runs the example.
     *
     * @param args not used
     */
    @SuppressWarnings("unused")
    public static void main(final String[] args) {
        new ExampleErrorTracker(args[0]);
    }

    @SuppressWarnings("FieldCanBeLocal")
    private final Viewer myViewer = new Viewer();

    /**
     * Creates a Viewer, adds the ErrorTracker to its decoder and opens a sample file.
     */
    public ExampleErrorTracker(final String filename) {

        //initialise JPedal viewer component

        myViewer.setupViewer();

        // add in a monitor
        //can also be PdfDecoderServer of PdfDecoderFX
        final PdfDecoder decode_pdf = (PdfDecoder) myViewer.getPdfDecoder();

        decode_pdf.addExternalHandler(new UserErrorTracker(), org.jpedal.external.Options.ErrorTracker);

        //open a file
        myViewer.executeCommand(ViewerCommands.OPENFILE, new File(filename));

    }

    /**
     * example implementation
     */
    private class UserErrorTracker extends DefaultErrorTracker {

        long timeAtStart;

        boolean userFailedPage;

        UserErrorTracker() {
        }


        @Override
        public String getPageFailureMessage() {

            if (userFailedPage) {
                return "Timed out on page";
            } else {
                return super.getPageFailureMessage();
            }
        }

        @Override
        //use to see if page failed
        public boolean ispageSuccessful() {
            return !userFailedPage && super.ispageSuccessful();
        }

        @Override
        // called every time we execute a Postscript command in data streams
        // (dataPointer/streamSize) gives indicator of amount decoded but page can
        // contain multiple streams
        public boolean checkForExitRequest(final int dataPointer, final int streamSize) {

            //gracefully allow us to fail if over certain time to decode
            final long timeElapsed = System.currentTimeMillis() - timeAtStart;
            System.out.println("Mill-Seconds elapsed=" + timeElapsed);
            if (timeElapsed > 1_500) {
                userFailedPage = true;
                return true;
            } else {
                return false;
            }
        }

        @Override
        public void finishedPageDecoding(final int rawPage) {
            System.out.println("----Completed page " + rawPage);
        }

        @Override
        //called when we start decoding page
        public void startedPageDecoding(final int rawPage) {
            System.out.println("----Started page " + rawPage);

            // get the current time
            timeAtStart = System.currentTimeMillis();
        }
    }
}