package com.atlassian.bitbucket.internal.mirroring.mirror.nav;

import com.atlassian.bitbucket.mirroring.mirror.UpstreamServer;
import com.atlassian.bitbucket.mirroring.mirror.UpstreamServerType;
import com.atlassian.bitbucket.nav.NavBuilder;
import com.atlassian.bitbucket.util.PageUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static com.atlassian.bitbucket.internal.mirroring.mirror.nav.DefaultMirroringNavBuilderTest.assertPagedUrl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class DefaultServerUpstreamNavBuilderTest {

    private static final String BASEURL = "http://bitbucket.company.com/bitbucket";
    private static final String REST_MIRRORING_PATH = "/rest/mirroring/latest";
    private static final String UPSTREAM_BASEURL = "https://upstream.server.com:7990/bitbucket";

    @Mock
    private NavBuilder navBuilder;
    @Mock
    private UpstreamServer upstream;
    private DefaultServerUpstreamNavBuilder builder;

    @Before
    public void setUpNavBuilder() {
        when(navBuilder.buildAbsolute()).thenReturn(BASEURL);
        when(upstream.getBaseUrl()).thenReturn(UPSTREAM_BASEURL);
        when(upstream.getType()).thenReturn(UpstreamServerType.BITBUCKET_SERVER);
        builder = new DefaultServerUpstreamNavBuilder(upstream);
    }

    @Test
    public void testAdminRestUrl() throws Exception {
        assertEquals(UPSTREAM_BASEURL + "/plugins/servlet/admin/mirrors", builder.admin().getAbsolute());
    }

    @Test
    public void testAnalyticsSettings() {
        MirroringUrl builder = this.builder.analyticsSettings();
        assertEquals(UPSTREAM_BASEURL + REST_MIRRORING_PATH + "/analyticsSettings", builder.getAbsolute());
        assertEquals(REST_MIRRORING_PATH + "/analyticsSettings", builder.getRelative());
    }

    @Test
    public void testAuthenticateRestUrl() {
        assertEquals(UPSTREAM_BASEURL + REST_MIRRORING_PATH + "/authenticate", builder.authenticate().getAbsolute());
    }

    @Test
    public void testAuthorizeAddonRestUrl() throws Exception {
        assertEquals(UPSTREAM_BASEURL + "/plugins/servlet/admin/mirrors", builder.authorizeAddon().getAbsolute());
    }

    @Test
    public void testMirrorsRestUrl() throws Exception {
        assertPagedUrl(UPSTREAM_BASEURL + REST_MIRRORING_PATH + "/mirrorServers",
                pageRequest -> builder.mirrors(pageRequest).getAbsolute(),
                PageUtils.newRequest(50, 100));
    }

    @Test
    public void testMirrorRequestsRestUrl() {
        assertEquals(UPSTREAM_BASEURL + REST_MIRRORING_PATH + "/requests", builder.mirrorRequests().getAbsolute());
    }

    @Test
    public void testRelativeToBase() throws Exception {
        assertEquals(UPSTREAM_BASEURL + "/foo/bar/baz",
                builder.relativeToBase("/foo/bar/baz").getAbsolute());
        // we don't say we will accept this but we try to be tolerant in what we accept
        assertEquals(UPSTREAM_BASEURL + "/foo/bar/baz",
                builder.relativeToBase("foo/bar/baz").getAbsolute());
    }

    @Test
    public void testSshKeys() {
        String url = builder.sshKeys().getAbsolute();
        assertNotNull(url);
        assertEquals(UPSTREAM_BASEURL + "/rest/ssh/latest/keys", url);
    }

    @Test
    public void testUpstreamRepositories() {
        assertPagedUrl(UPSTREAM_BASEURL + REST_MIRRORING_PATH + "/repos",
                pageRequest -> builder.repositories(pageRequest).getAbsolute(),
                PageUtils.newRequest(50, 100));
    }

    @Test
    public void testUpstreamRepository() {
        assertEquals(UPSTREAM_BASEURL + REST_MIRRORING_PATH + "/repos/1", builder.repositoryById("1").getAbsolute());
    }
}