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

import com.atlassian.bitbucket.mesh.io.MoreFiles;
import com.atlassian.bitbucket.mesh.junit.TemporaryDirectory;
import com.google.common.collect.ImmutableList;
import com.google.common.io.LineProcessor;
import org.junit.Rule;
import org.junit.Test;

import javax.annotation.Nonnull;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*;

public class PathHookStdinTest {

    @Rule
    public final TemporaryDirectory tempDir = new TemporaryDirectory();

    @Test
    public void testManualDeletionIsTreatedAsRelease() throws Exception {
        Path path = MoreFiles.write(tempDir.newFile(), "This is a test");

        PathHookStdin stdin = new PathHookStdin(path, 14L);
        assertEquals("This is a test", stdin.read());

        Files.delete(path); //Simulate an eager sysadmin purging temporary files
        assertTrue(stdin.isReleased());

        IllegalStateException thrown = assertThrows(IllegalStateException.class, stdin::open);
        assertThat(thrown.getMessage(), containsString("already been released"));
    }

    @Test
    public void testReadAndRelease() throws Exception {
        Path path = MoreFiles.write(tempDir.newFile(), "This is a test");

        PathHookStdin stdin = new PathHookStdin(path, 14L);
        assertEquals("This is a test", stdin.read());
        assertFalse(stdin.isReleased());

        stdin.release();
        assertTrue(stdin.isReleased());
        assertFalse("The hook data should have been deleted", Files.exists(path));

        IllegalStateException thrown = assertThrows(IllegalStateException.class, stdin::open);
        assertThat(thrown.getMessage(), containsString("already been released"));
    }

    @Test
    public void testReadLines() throws Exception {
        Path path = MoreFiles.write(tempDir.newFile(), "One\nTwo\nThree");

        PathHookStdin stdin = new PathHookStdin(path, 13L);
        assertEquals(13L, stdin.size());

        List<String> actual = stdin.readLines(new LineProcessor<List<String>>() {

            private final List<String> lines = new ArrayList<>();

            @Override
            public List<String> getResult() {
                return lines;
            }

            @Override
            public boolean processLine(@Nonnull String line) {
                lines.add(line);
                return true;
            }
        });
        assertNotNull(actual);
        assertEquals(ImmutableList.of("One", "Two", "Three"), ImmutableList.copyOf(actual));
    }
}