package com.camunda.fox.cycle.web.service.resource;

import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;

import java.util.Date;

import javax.inject.Inject;
import javax.ws.rs.core.Response;

import org.junit.After;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.kubek2k.springockito.annotations.ReplaceWithMock;
import org.kubek2k.springockito.annotations.SpringockitoContextLoader;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.camunda.fox.cycle.connector.ConnectorNode;
import com.camunda.fox.cycle.connector.ConnectorNodeType;
import com.camunda.fox.cycle.connector.ContentInformation;
import com.camunda.fox.cycle.entity.BpmnDiagram;
import com.camunda.fox.cycle.repository.BpmnDiagramRepository;

/**
 *
 * @author nico.rehwaldt
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
  loader = SpringockitoContextLoader.class,
  locations = { "classpath:/spring/mock/test-context.xml", "classpath:/spring/mock/test-persistence.xml" }
)
public class BpmnDiagramServiceTest {

  @Inject
  @ReplaceWithMock
  private ConnectorService connectorService;
  
  @Inject
  private BpmnDiagramService bpmnDiagramService;
  
  @Inject
  private BpmnDiagramRepository bpmnDiagramRepository;
  
  @After
  public void after() {
    bpmnDiagramRepository.deleteAll();
  }

  private static ConnectorNode DIAGRAM_NODE = new ConnectorNode("//mydiagram.bpmn", "my diagram.bpmn", 1l);
  
  @Test
  public void shouldNotServeImageIfImageIsOutOfDate() {
    BpmnDiagram diagram = diagramLastModified(now());
    
    // given
    given(connectorService.getContentInfo(DIAGRAM_NODE.getConnectorId(), DIAGRAM_NODE.getId(), ConnectorNodeType.PNG_FILE)).willReturn(contentInformationLastModified(earlier()));
    given(connectorService.getTypedContent(DIAGRAM_NODE.getConnectorId(), DIAGRAM_NODE.getId(), ConnectorNodeType.PNG_FILE)).willReturn(Response.ok().build());
    
    // when
    Object result = bpmnDiagramService.getImage(diagram.getId());
    
    // then
    assertThat(result, is(instanceOf(Response.class)));
    
    Response response = (Response) result;
    assertThat(response.getStatus(), is(Response.Status.NOT_FOUND.getStatusCode()));
  }
  
  @Test
  public void shouldServeImageIfNotOutOfDate() {
    BpmnDiagram diagram = diagramLastModified(earlier());
    
    // given
    given(connectorService.getContentInfo(DIAGRAM_NODE.getConnectorId(), DIAGRAM_NODE.getId(), ConnectorNodeType.PNG_FILE)).willReturn(contentInformationLastModified(now()));
    given(connectorService.getTypedContent(DIAGRAM_NODE.getConnectorId(), DIAGRAM_NODE.getId(), ConnectorNodeType.PNG_FILE)).willReturn(Response.ok().build());
    
    // when
    Object result = bpmnDiagramService.getImage(diagram.getId());
    
    assertThat(result, is(instanceOf(Response.class)));
    
    Response response = (Response) result;
    assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
  }

  @Test
  public void shouldNotServeImageMissing() {
    BpmnDiagram diagram = diagramLastModified(earlier());
    
    // given
    given(connectorService.getContentInfo(DIAGRAM_NODE.getConnectorId(), DIAGRAM_NODE.getId(), ConnectorNodeType.PNG_FILE)).willReturn(nonExistingContentInformation());
    
    // when
    Object result = bpmnDiagramService.getImage(diagram.getId());
    
    assertThat(result, is(instanceOf(Response.class)));
    
    Response response = (Response) result;
    assertThat(response.getStatus(), is(Response.Status.NOT_FOUND.getStatusCode()));
  }
  
  private BpmnDiagram diagramLastModified(Date date) {
    
    BpmnDiagram diagram = new BpmnDiagram("fox modeler", DIAGRAM_NODE);
    diagram.setLastModified(date);
    
    bpmnDiagramRepository.saveAndFlush(diagram);
    
    return diagram;
  }

  private ContentInformation nonExistingContentInformation() {
    return new ContentInformation(false, null);
  }

  private ContentInformation contentInformationLastModified(Date date) {
    return new ContentInformation(true, date);
  }

  private Date now() {
    return new Date();
  }

  private Date earlier() {
    return new Date(System.currentTimeMillis() - 20000);
  }
}

@@ -274,16 +274,60 @@
 Inject;%0A
+import javax.ws.rs.WebApplicationException;%0A
 import j
@@ -352,16 +352,16 @@
 sponse;%0A
-
 %0Aimport 
@@ -1009,16 +1009,48 @@
 itory;%0A%0A
+import junit.framework.Assert;%0A%0A
 /**%0A *%0A 
@@ -2199,32 +2199,44 @@
 .build());%0A    %0A
+    try %7B%0A  
     // when%0A    
@@ -2231,39 +2231,25 @@
 // when%0A    
-Object result =
+ 
  bpmnDiagram
@@ -2291,86 +2291,130 @@
     
-%0A
   
+%0A
   
-// then%0A
     
-a
+A
 ssert
-That(result, is(instanceOf(Response.class)));%0A    %0A
+.fail(%22Expected web application exception%22);%0A    %7D catch (WebApplicationException e) %7B%0A      // then%0A 
     
+ 
 Resp
@@ -2425,33 +2425,37 @@
  response = 
-(
+e.get
 Response
 ) result;%0A  
@@ -2438,34 +2438,30 @@
 .getResponse
-) result;%0A
+();%0A  
     assertTh
@@ -2525,32 +2525,38 @@
 StatusCode()));%0A
+    %7D%0A
   %7D%0A  %0A  @Test%0A 
@@ -3584,32 +3584,44 @@
 mation());%0A    %0A
+    try %7B%0A  
     // when%0A    
@@ -3616,39 +3616,25 @@
 // when%0A    
-Object result =
+ 
  bpmnDiagram
@@ -3672,78 +3672,128 @@
 ));%0A
+%0A  
     
-%0A    assertThat(result, is(instanceOf(Response.class)));%0A    %0A
+Assert.fail(%22Expected web application exception%22);%0A    %7D catch (WebApplicationException e) %7B%0A      // then%0A 
     
+ 
 Resp
@@ -3804,33 +3804,37 @@
  response = 
-(
+e.get
 Response
 ) result;%0A  
@@ -3817,34 +3817,30 @@
 .getResponse
-) result;%0A
+();%0A  
     assertTh
@@ -3908,24 +3908,30 @@
 usCode()));%0A
+    %7D%0A
   %7D%0A  %0A  pri

Fix test case