package com.atlassian.stash.internal.rest.renderer;

import com.atlassian.bitbucket.nav.NavBuilder;
import com.atlassian.bitbucket.rest.annotation.JsonSurrogate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.junit.Assert.assertSame;

@RunWith(MockitoJUnitRunner.class)
@SuppressWarnings("unused")
public class AggregateBuilderTest {
    @Mock
    private NavBuilder navBuilder;

    @Test(expected = IllegalArgumentException.class)
    public void testCantAddNonSurrogate() throws Exception {
        new AggregateBuilder(navBuilder).registerSurrogate(Object.class);
    }

    @JsonSurrogate(Object.class)
    public static class TestSurrogate {
    }

    @Test(expected = IllegalArgumentException.class)
    public void testCantAddSurrogateWithNeitherSingleArgCtorNorDoubleArgCtor() throws Exception {
        new AggregateBuilder(navBuilder).registerSurrogate(TestSurrogate.class);
    }

    @JsonSurrogate(Object.class)
    public static class TestSurrogate2 {
        public TestSurrogate2(Object o) {
        }
    }

    @Test
    public void testCanAddSurrogateWithSingleArgCtor() throws Exception {
        new AggregateBuilder(navBuilder).registerSurrogate(TestSurrogate2.class);
    }

    @JsonSurrogate(Object.class)
    public static class TestSurrogate3 {
        public TestSurrogate3(String o) {
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void testCantAddSurrogateWithSingleArgCtorWithWrongParamTypes() throws Exception {
        new AggregateBuilder(navBuilder).registerSurrogate(TestSurrogate3.class);
    }

    @JsonSurrogate(Object.class)
    public static class TestSurrogate4 {
        public TestSurrogate4(Object o, NavBuilder nb) {
        }
    }

    @Test
    public void testCanAddSurrogateWithDoubleArgCtor() throws Exception {
        new AggregateBuilder(navBuilder).registerSurrogate(TestSurrogate4.class);
    }

    @JsonSurrogate(Object.class)
    public static class TestSurrogate5 {
        public TestSurrogate5(String o, NavBuilder nb) {
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void testCanAddSurrogateWithDoubleArgCtorWithWrongParamTypes() throws Exception {
        new AggregateBuilder(navBuilder).registerSurrogate(TestSurrogate5.class);
    }

    @JsonSurrogate(Object.class)
    public static class TestSurrogate6 {
        public TestSurrogate6(Object o) {
            throw new NullPointerException();
        }
    }

    @Test
    public void testRenderingObjectWithSingleArgCtorThrowingException() throws Exception {
        AggregateBuilder builder = new AggregateBuilder(navBuilder);
        builder.registerSurrogate(TestSurrogate6.class);
        Object arg = new Object();
        assertSame(arg, builder.buildFor(arg));
    }

    @JsonSurrogate(Object.class)
    public static class TestSurrogate7 {
        public TestSurrogate7(Object o, NavBuilder nb) {
            throw new NullPointerException();
        }
    }

    @Test
    public void testRenderingObjectWithDoubleArgCtorThrowingException() throws Exception {
        AggregateBuilder builder = new AggregateBuilder(navBuilder);
        builder.registerSurrogate(TestSurrogate7.class);
        Object arg = new Object();
        assertSame(arg, builder.buildFor(arg));
    }
}
