/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2023 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jboss.installer.cleaner;

import org.apache.commons.io.IOUtils;
import org.jboss.installer.core.LoggerUtils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;

/**
 * Sets up classpath and starts a new process for {@link Cleaner}.
 */
public class CleanerBuilder {

    private final Path classPath;

    /**
     * extracts classes and resources needed to run the cleaner process into a temporary folder.
     *
     * @return path to a temporary folder with extracted classes.
     * @throws IOException if unable to create a folder or extract resources.
     */
    public CleanerBuilder() throws IOException {
        classPath = prepareCleaner();
    }

    private static Path prepareCleaner() throws IOException {
        LoggerUtils.systemLog.trace("Preparing cleaner classes");
        final Path tempDirectory = Files.createTempDirectory("eap-installer-cleaner");
        final String classFileName = Cleaner.class.getName().replace('.', '/') + ".class";
        final Path classFile = tempDirectory.resolve(classFileName);
        Files.createDirectories(classFile.getParent());
        Files.createFile(classFile);
        try (InputStream is = Cleaner.class.getClassLoader().getResourceAsStream(classFileName);
             OutputStream os = new FileOutputStream(classFile.toFile())) {
            IOUtils.copy(is, os);
        }
        LoggerUtils.systemLog.debug("Copied Cleaner classes to " + tempDirectory);

        return tempDirectory;
    }

    /**
     * starts a cleaner process in background.
     *
     * <b>SHOULD ONLY BE CALLED RIGHT BEFORE PARENT PROCESS EXITS</b>
     *
     * @param removedPath - path to be removed
     * @throws IOException if unable to start a process
     */
    public void spawnCleanerProcess(Path removedPath) throws IOException {
        LoggerUtils.systemLog.debug("Spawining cleaner process to remove " + removedPath + " with " + classPath);
        final ProcessBuilder pb = new ProcessBuilder("java", "-cp", classPath.toString(),
                Cleaner.class.getName(), "-DdeletePath=" +classPath, "-DdeletePath="+removedPath);
        Process p = pb.start();
        LoggerUtils.systemLog.trace("Started cleaner process: " + p.pid());
    }
}
