package com.atlassian.bitbucket.internal.mirroring.upstream;

import com.atlassian.bitbucket.internal.mirroring.jwt.JwtTokenGenerationException;
import com.atlassian.bitbucket.internal.mirroring.jwt.JwtTokenHelper;
import com.atlassian.jwt.httpclient.CanonicalHttpUriRequest;
import com.atlassian.oauth.Consumer;
import com.atlassian.oauth.consumer.ConsumerService;
import com.atlassian.plugin.connect.bitbucket.BitbucketAddonAccessor;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Optional;

import static java.util.Optional.empty;
import static java.util.Optional.of;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class MirrorLinkServiceTest {

    @Mock
    private BitbucketAddonAccessor connectAddonAccessor;
    @Mock
    private ConsumerService consumerService;
    @Mock
    private JwtTokenHelper jwtTokenHelper;

    @InjectMocks
    private DefaultMirrorLinkService jwtMirrorTokenService;

    @Before
    public void setUp() throws JwtTokenGenerationException {
        when(connectAddonAccessor.getDescriptor(isA(String.class))).thenReturn("{" +
                "\"links\": {" +
                "\"rest\": \"/some/rest/url\"" +
                "}" +
                "}");
        when(connectAddonAccessor.getSharedSecret(eq("addon-key"))).thenReturn(of("secret"));

        Consumer consumer = new Consumer.InstanceBuilder("issuer-id")
                .name("consumer")
                .signatureMethod(Consumer.SignatureMethod.HMAC_SHA1)
                .build();
        when(consumerService.getConsumer()).thenReturn(consumer);
        when(jwtTokenHelper.generateToken(isA(CanonicalHttpUriRequest.class), anyLong(), eq("issuer-id"), anyString(),
                eq("secret"))).thenReturn("token");
    }

    @Test
    public void testGenerateToken() {
        InternalMirrorServer mirrorServer = mock(InternalMirrorServer.class);
        when(mirrorServer.getAddonKey()).thenReturn("addon-key");
        when(mirrorServer.getBaseUrl()).thenReturn("base-url");

        Optional<String> optionalLink = jwtMirrorTokenService.generateAuthorizedLink(mirrorServer, "");
        assertEquals("base-url/some/rest/url?jwt=token", optionalLink.get());
    }

    @Test
    public void testGenerateTokenNoMirrorFound() {
        InternalMirrorServer mirrorServer = mock(InternalMirrorServer.class);
        when(mirrorServer.getAddonKey()).thenReturn("addon-key-2");
        when(mirrorServer.getBaseUrl()).thenReturn("base-url");
        when(connectAddonAccessor.getSharedSecret("addon-key-2")).thenReturn(empty());

        Optional optionalLink = jwtMirrorTokenService.generateAuthorizedLink(mirrorServer, "");
        assertFalse(optionalLink.isPresent());
    }

}
