/*
 * Copyright (c) 1997-2019 IDRsolutions (https://www.idrsolutions.com)
 */

package org.jpedal.examples;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * Helper class that can be used to convert Office documents to PDF using LibreOffice
 */
public final class DocumentToPDFConverter {

    private DocumentToPDFConverter() {
    }

    /**
     * Uses LibreOffice to convert an office document to PDF using the provided LibreOffice executable path.
     <p>
     * Creates a file with the same name (with .pdf extension) in the same directory as the source file.
     <p>
     * If the output file already exists, it will not be overwritten and an IOException will be thrown.
     *
     @param document                  Office document to convert to PDF
     @param libreOfficeExecutablePath Absolute path for the LibreOffice executable to use to convert the document
     @param allowOverwrite            Boolean flag on whether the output file can be overwritten
     @return The exit code of the LibreOffice process (usually 0 regardless of success or failure)
     @throws IOException          If the LibreOffice executable was not found, the document does not exist, the document does
     *                              not have a valid file extension, or the output file already exists (and allowOverwrite 
     *                              is set to false)
     @throws InterruptedException If the conversion process gets interrupted
     */
    public static int convert(final File document, final String libreOfficeExecutablePath, final boolean allowOverwritethrows IOException, InterruptedException {

        if (!document.exists()) {
            throw new FileNotFoundException(document.getAbsolutePath());
        }

        final int idx = document.getAbsolutePath().lastIndexOf('.');
        if (idx < 1) {
            throw new IOException("Document does not have a valid file extension: " + document.getAbsolutePath());
        }

        final String outputDocumentPath = document.getAbsolutePath().substring(0, idx".pdf";
        final File outputDocument = new File(outputDocumentPath);
        if (outputDocument.exists()) {
            if (allowOverwrite) {
                outputDocument.delete();
            else {
                throw new IOException("Output file already exists: " + outputDocumentPath);
            }
        }

        final ProcessBuilder pb = new ProcessBuilder(libreOfficeExecutablePath, "--headless""--convert-to""pdf", document.getName());
        pb.directory(document.getParentFile());
        return pb.start().waitFor();

    }
    
    /**
     * Uses LibreOffice to convert an office document to PDF using the provided LibreOffice executable path.
     <p>
     * Creates a file with the same name (with .pdf extension) in the same directory as the source file.
     <p>
     * If the output file already exists, it will not be overwritten and an IOException will be thrown.
     *
     @param document                  Office document to convert to PDF
     @param libreOfficeExecutablePath Absolute path for the LibreOffice executable to use to convert the document
     @return The exit code of the LibreOffice process (usually 0 regardless of success or failure)
     @throws IOException          If the LibreOffice executable was not found, the document does not exist, the document does
     *                              not have a valid file extension, or the output file already exists (will not overwrite)
     @throws InterruptedException If the conversion process gets interrupted
     */
    public static int convert(final File document, final String libreOfficeExecutablePaththrows IOException, InterruptedException {
        return convert(document, libreOfficeExecutablePath, false);
    }

    private static final String[] FILE_TYPES = {
            "ODT""FODT""ODS""FODS""ODP""FODP""ODB""ODG""FODG""ODF"// LibreOffice
            "SXW""STW""SXC""STC""SXI""STI""SXD""STD""SXM"// OpenOffice
            "DOCX""XLSX""PPTX",
            "DOC""DOT",
            "PPT""PPS""POT",
            "XLS""XLW""XLT"
    };

    private static final Set<String> FILE_TYPES_LIST = new HashSet<>(Arrays.asList(FILE_TYPES));

    /**
     * Returns whether the provided file has a convertible file type
     *
     @param file file to check
     @return whether provided file is convertible
     */
    public static boolean hasConvertibleFileType(final File file) {
        final int idx = file.getAbsolutePath().lastIndexOf('.');
        return idx > && FILE_TYPES_LIST.contains(file.getAbsolutePath().substring(idx + 1).toUpperCase());
    }

}