package org.codehaus.plexus.archiver.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;

import org.codehaus.plexus.components.io.functions.FileSupplier;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

/**
 * Utility class for work with {@link PlexusIoResource} instances.
 */
public class ResourceUtils {

    /**
     * Private constructor, to prevent accidental implementation.
     */
    private ResourceUtils() {
        // Does nothing
    }

    /**
     * Queries, whether the given source is up-to-date relative to
     * the given destination.
     */
    public static boolean isUptodate(PlexusIoResource source, File destination) {
        return isUptodate(source, destination.lastModified());
    }

    /**
     * Queries, whether the given source is up-to-date relative to
     * the given modification date.
     */
    public static boolean isUptodate(PlexusIoResource source, long destinationDate) {
        return isUptodate(source.getLastModified(), destinationDate);
    }

    /**
     * Queries, whether the given source is up-to-date relative to
     * the given modification date.
     */
    public static boolean isUptodate(long sourceDate, long destinationDate) {
        if (sourceDate == PlexusIoResource.UNKNOWN_MODIFICATION_DATE) {
            return false;
        }

        if (destinationDate == 0) {
            return false;
        }

        return destinationDate >= sourceDate;
    }

    /**
     * Copies the sources contents to the given destination file.
     */
    public static void copyFile(PlexusIoResource in, File outFile) throws IOException {
        try (InputStream input = in.getContents()) {
            Files.copy(input, outFile.toPath(), REPLACE_EXISTING);
        }
    }

    /**
     * Copies the sources contents to the given destination file.
     */
    public static void copyFile(InputStream input, File outFile) throws IOException {
        Files.copy(input, outFile.toPath(), REPLACE_EXISTING);
    }

    /**
     * Checks, whether the resource and the file are identical.
     */
    public static boolean isSame(PlexusIoResource resource, File file) {
        if (resource instanceof FileSupplier) {
            File resourceFile = ((FileSupplier) resource).getFile();
            return file.equals(resourceFile);
        }
        return false;
    }

    /**
     * Checks, whether the resource and the file are identical.
     * Uses {@link File#getCanonicalFile()} for comparison, which is much
     * slower than comparing the files.
     */
    public static boolean isCanonicalizedSame(PlexusIoResource resource, File file) throws IOException {
        if (resource instanceof FileSupplier) {
            File resourceFile = ((FileSupplier) resource).getFile();
            return file.getCanonicalFile().equals(resourceFile.getCanonicalFile());
        }
        return false;
    }
}
