package com.atlassian.bitbucket.mesh.git.hook;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;

import static java.util.Objects.requireNonNull;

class PathHookStdin extends AbstractHookStdin {

    private static final Logger log = LoggerFactory.getLogger(PathHookStdin.class);

    private final Path path;

    PathHookStdin(@Nonnull Path path, long size) {
        super(size);

        this.path = requireNonNull(path, "path");
    }

    @Override
    public boolean isReleased() {
        return super.isReleased() || !Files.exists(path);
    }

    @Nonnull
    @Override
    InputStream doOpen() throws IOException {
        try {
            return Files.newInputStream(path);
        } catch (FileNotFoundException | NoSuchFileException e) {
            //If the file somehow ends up deleted out from under us (think sysadmin manually purging
            //temporary files), treat stdin as released. Even though isReleased has this check, we
            //need handling here too because the check can be racy
            throw new IllegalStateException("Hook stdin has already been released");
        }
    }

    @Override
    void doRelease() {
        try {
            Files.delete(path);
        } catch (FileNotFoundException | NoSuchFileException e) {
            //The temp file has already been deleted
        } catch (IOException e) {
            log.warn("Failed to delete buffered hook stdin at {}", path, e);
        }
    }
}
