package com.atlassian.bitbucket.mesh.git.builder.checkrefformat;

import com.atlassian.bitbucket.mesh.AbstractWiredTest;
import com.atlassian.bitbucket.mesh.git.builder.GitProcess;
import com.atlassian.bitbucket.mesh.git.builder.GitProcessBuilderFactory;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

public class GitCheckRefFormatTest extends AbstractWiredTest {

    @Autowired
    private GitProcessBuilderFactory builderFactory;

    @Test
    public void testGoodRefName() {
        assertTrue(createCommand("that/should/work").run());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testRefNameMustNotBeBlank() {
        createCommand("").run();
    }

    @Test
    public void testRefNameWithWhitespace() {
        assertFalse(createCommand("f u l l/ o f/ w h i t e s p a c e").run());
    }

    @Test
    public void testMaliciousName() {
        assertFalse(createCommand("-- bad/stuff").run());
    }

    @Test
    public void testRefNameLeadingSlash() {
        assertFalse(createCommand("/ref/that/starts/with/slash").run());
    }

    @Test
    public void testRefNameTrailingSlash() {
        assertFalse(createCommand("ref/that/ends/with/slash/").run());
    }

    @Test
    public void testRefNameWithDoubleSlash() {
        assertFalse(createCommand("ref/that/has/double//slash").run());
    }

    @Test
    public void testRefNameWithoutSlash() {
        assertFalse(createCommand("noslashhere").run());
    }

    @Test
    public void testRefNameWithLeadingDot() {
        assertFalse(createCommand("ref/that/has/.leading/dot").run());
    }

    @Test
    public void testRefNameWithDotLock() {
        assertFalse(createCommand("ref/that/has/dot.lock").run());
    }

    @Test
    public void testRefNameTwoDots() {
        assertFalse(createCommand("ref/with../two/dots").run());
    }

    @Test
    public void testRefNameWithTilde() {
        assertFalse(createCommand("ref/with/~tilde").run());
    }

    @Test
    public void testRefNameWithCaret() {
        assertFalse(createCommand("ref/with/^caret").run());
    }

    @Test
    public void testRefNameWithColon() {
        assertFalse(createCommand("ref/with/:colon").run());
    }

    @Test
    public void testRefNameWithQuestionMark() {
        assertFalse(createCommand("ref/with/?question/mark").run());
    }

    @Test
    public void testRefNameWithAsterisk() {
        assertFalse(createCommand("ref/with/*asterisk").run());
    }

    @Test
    public void testRefNameWithSquareBracket() {
        assertFalse(createCommand("ref/with/[bracket").run());
    }

    @Test
    public void testRefNameWithReflogEntryNotation() {
        assertFalse(createCommand("ref/with/@{reflog}").run());
    }

    @Test
    public void testRefNameWithTrailingDot() {
        assertFalse(createCommand("ref/with/trailing/dot.").run());
    }

    @Test
    public void testRefNameWithBackslash() {
        assertFalse(createCommand("ref/with/backsla\\sh").run());
    }

    private GitCheckRefFormat createBuilder() {
        return builderFactory.builder().checkRefFormat();
    }

    private GitProcess<Boolean> createCommand(String refName) {
        CheckRefFormatProcessHandler handler = new CheckRefFormatProcessHandler();
        return createBuilder()
                .ref(refName)
                .build(handler);
    }
}