package org.datacite.mds.service.impl;

import static org.easymock.EasyMock.*;
import net.handle.hdllib.AbstractMessage;
import net.handle.hdllib.AbstractRequest;
import net.handle.hdllib.GenericResponse;
import net.handle.hdllib.HandleResolver;
import net.handle.hdllib.HandleValue;

import org.datacite.mds.service.HandleException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/META-INF/spring/applicationContext.xml")
public class HandleServiceImplTest {

    @Autowired
    private HandleServiceImpl service;
    
    private static final String doi = "10.5072/test";
    private static final String url = "http://example.com";

    @Before
    public void setup() {
        service.dummyMode = false;
        service.resolver = createMock(HandleResolver.class);
    }
    
    @After
    public void tearDown() {
        service.dummyMode = true;
    }

    @Test
    public void testCreate() throws Exception {
        mockResponseCode(AbstractMessage.RC_SUCCESS);
        replay(service.resolver);
        service.create(doi, url);
    }

    @Test(expected = HandleException.class)
    public void testCreateError() throws Exception {
        mockResponseCode(AbstractMessage.RC_ERROR);
        replay(service.resolver);
        service.create(doi, url);
    }

    @Test(expected = HandleException.class)
    public void testCreateException() throws Exception {
        mockResponseException();
        replay(service.resolver);
        service.create(doi, url);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testCreateIllegalArgument1() throws HandleException {
        service.create(null, null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testCreateIllegalArgument2() throws HandleException {
        service.create("", "");
    }

    @Test
    public void testUpdate() throws Exception {
        mockExistingHandle();
        mockResponseCode(AbstractMessage.RC_SUCCESS);
        replay(service.resolver);
        service.update(doi, url);
    }

    @Test(expected = HandleException.class)
    public void testUpdateNonExistingHandle() throws Exception {
        mockNonExistingHandle();
        replay(service.resolver);
        service.update(doi, url);
    }
    
    @Test(expected = HandleException.class)
    public void testUpdateError() throws Exception {
        mockExistingHandle();
        mockResponseCode(AbstractMessage.RC_ERROR);
        replay(service.resolver);
        service.update(doi, url);
    }
    
    @Test(expected = HandleException.class)
    public void testUpdateException() throws Exception {
        mockExistingHandle();
        mockResponseException();
        replay(service.resolver);
        service.update(doi, url);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testUpdateIllegalArgument1() throws HandleException {
        service.update(null, null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testUpdateIllegalArgument2() throws HandleException {
        service.update("", "");
    }

    void mockResponseCode(int respondeCode) throws net.handle.hdllib.HandleException {
        GenericResponse response = new GenericResponse(0, respondeCode);
        expect(service.resolver.processRequest(anyObject(AbstractRequest.class))).andReturn(response);
    }

    void mockResponseException() throws net.handle.hdllib.HandleException {
        net.handle.hdllib.HandleException ex = new net.handle.hdllib.HandleException(0);
        expect(service.resolver.processRequest(anyObject(AbstractRequest.class))).andThrow(ex);
    }

    void mockExistingHandle() throws net.handle.hdllib.HandleException {
        HandleValue[] values = { new HandleValue(1, "URL".getBytes(), url.getBytes()) };
        expect(service.resolver.resolveHandle(eq(doi), anyObject(String[].class), anyObject(int[].class)))//
                .andReturn(values);
    }

    void mockNonExistingHandle() throws net.handle.hdllib.HandleException {
        HandleValue[] values = {};
        expect(service.resolver.resolveHandle(eq(doi), anyObject(String[].class), anyObject(int[].class)))//
                .andReturn(values);
    }

}

@@ -945,16 +945,21 @@
 le.com%22;
+%0A    
 %0A%0A    @B
@@ -1877,32 +1877,178 @@
 stCreate
-IllegalArgument1
+EmptyDoi() throws HandleException %7B%0A        service.create(%22%22, url);%0A    %7D%0A%0A    @Test(expected = IllegalArgumentException.class)%0A    public void testCreateNullDoi
 () throw
@@ -2088,35 +2088,34 @@
 ce.create(null, 
-nul
+ur
 l);%0A    %7D%0A%0A    @
@@ -2100,33 +2100,32 @@
 ll, url);%0A    %7D%0A
-%0A
     @Test(expect
@@ -2187,32 +2187,178 @@
 stCreate
-IllegalArgument2
+EmptyUrl() throws HandleException %7B%0A        service.create(doi, %22%22);%0A    %7D%0A%0A    @Test(expected = IllegalArgumentException.class)%0A    public void testCreateNullUrl
 () throw
@@ -2396,30 +2396,33 @@
 vice.create(
-%22%22, %22%22
+doi, null
 );%0A    %7D%0A%0A  
@@ -3437,24 +3437,170 @@
 date
-IllegalArgument1
+EmptyDoi() throws HandleException %7B%0A        service.update(%22%22, url);%0A    %7D%0A%0A    @Test(expected = IllegalArgumentException.class)%0A    public void testUpdateNullDoi
 () t
@@ -3652,19 +3652,18 @@
 e(null, 
-nul
+ur
 l);%0A    
@@ -3656,33 +3656,32 @@
 ll, url);%0A    %7D%0A
-%0A
     @Test(expect
@@ -3747,24 +3747,170 @@
 date
-IllegalArgument2
+EmptyUrl() throws HandleException %7B%0A        service.update(doi, %22%22);%0A    %7D%0A%0A    @Test(expected = IllegalArgumentException.class)%0A    public void testUpdateNullUrl
 () t
@@ -3960,14 +3960,17 @@
 ate(
-%22%22, %22%22
+doi, null
 );%0A 
@@ -3966,32 +3966,36 @@
 i, null);%0A    %7D%0A
+    
 %0A    void mockRe

add missing test for HandleService