

package org.opensingular.lib.commons.pdf;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

/**
 * Classe utilitária para a manipulação de PDF's em sistemas Linux/Unix.
 * Essa versão sobre escreve as chamadas nativas da classe
 * {@link PDFUtil} com as equivalentes para o sistema Linux/Unix.
 */
final class PDFUtilUnix extends PDFUtil {

    @Override
    protected @Nonnull String fixPathArg(@Nullable File arq) {
        if(arq != null) {
            return "file://".concat(arq.getAbsolutePath());
        }
        throw new SingularPDFException("Nenhum arquivo informado");
    }

    @Override
    protected void writeToFile(File destination, String content) throws SingularPDFException {
        try(FileWriter fw = new FileWriter(destination)) {
            fw.write(content);
        } catch (IOException e) {
            throw new SingularPDFException("Erro escrevendo conteúdo para arquivo " + destination.getAbsolutePath(), e);
        }
    }

    @Override
    protected
    @Nonnull
    File runProcess(@Nonnull List<String> commandAndArgs, @Nonnull File expectedFile) throws SingularPDFException {
        getLogger().info(commandAndArgs.toString());

        try {
            ProcessBuilder pb = new ProcessBuilder(commandAndArgs);
            pb.environment().put("LD_LIBRARY_PATH", getWkhtml2pdfHome().getAbsolutePath());
            Process process = pb.start();
            process.waitFor();

            return generateFile(process, expectedFile);
        } catch (IOException | InterruptedException e) {
            throw new SingularPDFException(e);
        }

    }
    /**
     * Gera o arquivo através do processo especificado.
     *
     * @param expectedFile    o arquivo a ser criado.
     * @return o arquivo criado.
     */
    private File generateFile(Process process, File expectedFile) throws SingularPDFException {

        boolean done    = false;
        boolean success = true;
        try(BufferedReader outReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
            String line = outReader.readLine();
            while (line != null) {
                getLogger().info(line);
                line = outReader.readLine();
            }
            line = errReader.readLine();
            while (line != null) {
                if (line.startsWith("Done")) {
                    done = true;
                } else if (line.startsWith("Warning:")) {
                    getLogger().warn(line);
                } else if (line.startsWith("Error:")) {
                    success = false;
                    getLogger().error(line);
                } else {
                    getLogger().info(line);
                }
                line = errReader.readLine();
            }
        } catch (IOException e) {
            throw new SingularPDFException(e);
        }
        if (done && success && expectedFile.exists()) {
            return expectedFile;
        }

        throw new SingularPDFException(
                String.format("O arquivo não foi gerado:  done:%b success:%b file.exists():%b", done, success,
                        expectedFile.exists()));
    }
}