/*
 * Copyright 2017 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jbpm.designer.web.server;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jbpm.designer.helper.TestHttpServletRequest;
import org.jbpm.designer.repository.RepositoryBaseTest;
import org.jbpm.designer.web.profile.IDiagramProfileService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class FileStoreServletTest extends RepositoryBaseTest {

    @Mock
    IDiagramProfileService profileService;

    @Spy
    @InjectMocks
    private FileStoreServlet servlet = new FileStoreServlet();

    @Before
    public void setup() {
        super.setup();
        when(profileService.findProfile(any(HttpServletRequest.class),
                                        anyString())).thenReturn(profile);
    }

    @After
    public void teardown() {
        super.teardown();
    }

    @Test
    public void testDoPostFindProfile() throws Exception {

        HttpServletRequest request = mock(HttpServletRequest.class);
        try {
            servlet.doPost(request,
                           mock(HttpServletResponse.class));
        } catch (Exception e) {
            // exception thrown due to mocked request and response
        }
        verify(profileService,
               times(1)).findProfile(request,
                                     "jbpm");
    }

    @Test
    public void testDoPostProfileAlreadySet() throws Exception {
        HttpServletRequest request = mock(HttpServletRequest.class);
        servlet.profile = profile;
        try {
            servlet.doPost(request,
                           mock(HttpServletResponse.class));
        } catch (Exception e) {
            // exception thrown due to mocked request and response
        }
        verify(profileService,
               never()).findProfile(any(HttpServletRequest.class),
                                    anyString());
    }

    @Test
    public void testEsapeRetData() throws Exception {
        Map<String, String> params = new HashMap<>();
        params.put("data",
                   "<hello>some value</hello>");

        servlet.profile = profile;
        try {
            servlet.doPost(new TestHttpServletRequest(params),
                           mock(HttpServletResponse.class));

            assertNotNull(servlet.getRetData());
            assertEquals("&lt;hello&gt;some value&lt;/hello&gt;",
                         servlet.getRetData());
        } catch (Exception e) {
            // exception thrown due to mocked request and response
        }
        verify(profileService,
               never()).findProfile(any(HttpServletRequest.class),
                                    anyString());
    }

    @Test
    public void testEncodedRetData() throws Exception {
        Map<String, String> params = new HashMap<>();
        // full bpmn2 process (base64 encoded)
        params.put("data_encoded",
                   "[encoded data, 12892 characters]");

        servlet.profile = profile;

        servlet.doPost(new TestHttpServletRequest(params),
                       mock(HttpServletResponse.class));

        assertNotNull(servlet.getRetData());
        assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                             "<bpmn2:definitions xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.omg.org/bpmn20\" xmlns:bpmn2=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:bpsim=\"http://www.bpsim.org/schemas/1.0\" xmlns:color=\"http://www.omg.org/spec/BPMN/non-normative/color\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" xmlns:drools=\"http://www.jboss.org/drools\" id=\"_6sPDIFEkEeeF7cLzdZ522w\" xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd http://www.jboss.org/drools drools.xsd http://www.bpsim.org/schemas/1.0 bpsim.xsd\" exporter=\"jBPM Designer\" exporterVersion=\"6.2.0\" expressionLanguage=\"http://www.mvel.org/2.0\" targetNamespace=\"http://www.omg.org/bpmn20\" typeLanguage=\"http://www.java.com/javaTypes\">\n" +
                             "  <bpmn2:itemDefinition id=\"__2346040E-86BD-4794-A7E6-4720414058FF_SkippableInputXItem\" structureRef=\"Object\"/>\n" +
                             "  <bpmn2:process id=\"evaluation.viewsource\" drools:packageName=\"org.jbpm\" drools:version=\"1.0\" name=\"viewsource\" isExecutable=\"true\">\n" +
                             "    <bpmn2:startEvent id=\"processStartEvent\" drools:selectable=\"true\" color:background-color=\"#9acd32\" color:border-color=\"#000000\" color:color=\"#000000\" name=\"\">\n" +
                             "      <bpmn2:extensionElements>\n" +
                             "        <drools:metaData name=\"elementname\">\n" +
                             "          <drools:metaValue><![CDATA[]]></drools:metaValue>\n" +
                             "        </drools:metaData>\n" +
                             "      </bpmn2:extensionElements>\n" +
                             "      <bpmn2:outgoing>_90A843CC-9768-44EE-9610-3AB864EA65A2</bpmn2:outgoing>\n" +
                             "    </bpmn2:startEvent>\n" +
                             "    <bpmn2:userTask id=\"_2346040E-86BD-4794-A7E6-4720414058FF\" drools:selectable=\"true\" drools:scriptFormat=\"http://www.java.com/java\" color:background-color=\"#fafad2\" color:border-color=\"#000000\" color:color=\"#000000\" name=\"&#26053;&#12525;&#20140;&#38738;&#21033;&#12475;&#12512;&#12524; &#24369;&#25913;&#12501;&#12520;&#12473;&#27874;&#24220;&#12363;&#12400;&#12412;\">\n" +
                             "      <bpmn2:extensionElements>\n" +
                             "        <drools:metaData name=\"elementname\">\n" +
                             "          <drools:metaValue><![CDATA[旅ロ京青利セムレ\n" +
                             "弱改フヨス波府かばぼ]]></drools:metaValue>\n" +
                             "        </drools:metaData>\n" +
                             "      </bpmn2:extensionElements>\n" +
                             "      <bpmn2:incoming>_90A843CC-9768-44EE-9610-3AB864EA65A2</bpmn2:incoming>\n" +
                             "      <bpmn2:outgoing>_4565A230-3E22-45C9-AD0F-9A3159E15CEB</bpmn2:outgoing>\n" +
                             "      <bpmn2:ioSpecification id=\"_6sPDIVEkEeeF7cLzdZ522w\">\n" +
                             "        <bpmn2:dataInput id=\"_2346040E-86BD-4794-A7E6-4720414058FF_SkippableInputX\" drools:dtype=\"Object\" itemSubjectRef=\"__2346040E-86BD-4794-A7E6-4720414058FF_SkippableInputXItem\" name=\"Skippable\"/>\n" +
                             "        <bpmn2:inputSet id=\"_6sPDIlEkEeeF7cLzdZ522w\">\n" +
                             "          <bpmn2:dataInputRefs>_2346040E-86BD-4794-A7E6-4720414058FF_SkippableInputX</bpmn2:dataInputRefs>\n" +
                             "        </bpmn2:inputSet>\n" +
                             "        <bpmn2:outputSet id=\"_6sPDI1EkEeeF7cLzdZ522w\"/>\n" +
                             "      </bpmn2:ioSpecification>\n" +
                             "      <bpmn2:dataInputAssociation id=\"_6sPDJFEkEeeF7cLzdZ522w\">\n" +
                             "        <bpmn2:targetRef>_2346040E-86BD-4794-A7E6-4720414058FF_SkippableInputX</bpmn2:targetRef>\n" +
                             "        <bpmn2:assignment id=\"_6sPDJVEkEeeF7cLzdZ522w\">\n" +
                             "          <bpmn2:from xsi:type=\"bpmn2:tFormalExpression\" id=\"_6sPDJlEkEeeF7cLzdZ522w\">true</bpmn2:from>\n" +
                             "          <bpmn2:to xsi:type=\"bpmn2:tFormalExpression\" id=\"_6sPDJ1EkEeeF7cLzdZ522w\">_2346040E-86BD-4794-A7E6-4720414058FF_SkippableInputX</bpmn2:to>\n" +
                             "        </bpmn2:assignment>\n" +
                             "      </bpmn2:dataInputAssociation>\n" +
                             "    </bpmn2:userTask>\n" +
                             "    <bpmn2:sequenceFlow id=\"_90A843CC-9768-44EE-9610-3AB864EA65A2\" drools:selectable=\"true\" color:background-color=\"#000000\" color:border-color=\"#000000\" color:color=\"#000000\" sourceRef=\"processStartEvent\" targetRef=\"_2346040E-86BD-4794-A7E6-4720414058FF\"/>\n" +
                             "    <bpmn2:endEvent id=\"_DEDB1C64-835C-4DEC-818A-8C0D8B95FDBC\" drools:selectable=\"true\" color:background-color=\"#ff6347\" color:border-color=\"#000000\" color:color=\"#000000\" name=\"\">\n" +
                             "      <bpmn2:extensionElements>\n" +
                             "        <drools:metaData name=\"elementname\">\n" +
                             "          <drools:metaValue><![CDATA[]]></drools:metaValue>\n" +
                             "        </drools:metaData>\n" +
                             "      </bpmn2:extensionElements>\n" +
                             "      <bpmn2:incoming>_4565A230-3E22-45C9-AD0F-9A3159E15CEB</bpmn2:incoming>\n" +
                             "    </bpmn2:endEvent>\n" +
                             "    <bpmn2:sequenceFlow id=\"_4565A230-3E22-45C9-AD0F-9A3159E15CEB\" drools:selectable=\"true\" color:background-color=\"#000000\" color:border-color=\"#000000\" color:color=\"#000000\" sourceRef=\"_2346040E-86BD-4794-A7E6-4720414058FF\" targetRef=\"_DEDB1C64-835C-4DEC-818A-8C0D8B95FDBC\"/>\n" +
                             "  </bpmn2:process>\n" +
                             "  <bpmndi:BPMNDiagram id=\"_6sPDKFEkEeeF7cLzdZ522w\">\n" +
                             "    <bpmndi:BPMNPlane id=\"_6sPDKVEkEeeF7cLzdZ522w\" bpmnElement=\"evaluation.viewsource\">\n" +
                             "      <bpmndi:BPMNShape id=\"_6sPDKlEkEeeF7cLzdZ522w\" bpmnElement=\"processStartEvent\">\n" +
                             "        <dc:Bounds height=\"30.0\" width=\"30.0\" x=\"120.0\" y=\"165.0\"/>\n" +
                             "      </bpmndi:BPMNShape>\n" +
                             "      <bpmndi:BPMNShape id=\"_6sPDK1EkEeeF7cLzdZ522w\" bpmnElement=\"_2346040E-86BD-4794-A7E6-4720414058FF\">\n" +
                             "        <dc:Bounds height=\"146.0\" width=\"201.0\" x=\"225.0\" y=\"75.0\"/>\n" +
                             "      </bpmndi:BPMNShape>\n" +
                             "      <bpmndi:BPMNShape id=\"_6sPDLFEkEeeF7cLzdZ522w\" bpmnElement=\"_DEDB1C64-835C-4DEC-818A-8C0D8B95FDBC\">\n" +
                             "        <dc:Bounds height=\"28.0\" width=\"28.0\" x=\"570.0\" y=\"270.0\"/>\n" +
                             "      </bpmndi:BPMNShape>\n" +
                             "      <bpmndi:BPMNEdge id=\"_6sPDLVEkEeeF7cLzdZ522w\" bpmnElement=\"_90A843CC-9768-44EE-9610-3AB864EA65A2\" sourceElement=\"_6sPDKlEkEeeF7cLzdZ522w\" targetElement=\"_6sPDK1EkEeeF7cLzdZ522w\">\n" +
                             "        <di:waypoint xsi:type=\"dc:Point\" x=\"135.0\" y=\"180.0\"/>\n" +
                             "        <di:waypoint xsi:type=\"dc:Point\" x=\"325.5\" y=\"148.0\"/>\n" +
                             "      </bpmndi:BPMNEdge>\n" +
                             "      <bpmndi:BPMNEdge id=\"_6sPDLlEkEeeF7cLzdZ522w\" bpmnElement=\"_4565A230-3E22-45C9-AD0F-9A3159E15CEB\" sourceElement=\"_6sPDK1EkEeeF7cLzdZ522w\" targetElement=\"_6sPDLFEkEeeF7cLzdZ522w\">\n" +
                             "        <di:waypoint xsi:type=\"dc:Point\" x=\"325.5\" y=\"148.0\"/>\n" +
                             "        <di:waypoint xsi:type=\"dc:Point\" x=\"584.0\" y=\"284.0\"/>\n" +
                             "      </bpmndi:BPMNEdge>\n" +
                             "    </bpmndi:BPMNPlane>\n" +
                             "  </bpmndi:BPMNDiagram>\n" +
                             "  <bpmn2:relationship id=\"_6sPDL1EkEeeF7cLzdZ522w\" type=\"BPSimData\">\n" +
                             "    <bpmn2:extensionElements>\n" +
                             "      <bpsim:BPSimData>\n" +
                             "        <bpsim:Scenario xsi:type=\"bpsim:Scenario\" id=\"default\" name=\"Simulationscenario\">\n" +
                             "          <bpsim:ScenarioParameters xsi:type=\"bpsim:ScenarioParameters\" baseTimeUnit=\"min\"/>\n" +
                             "          <bpsim:ElementParameters xsi:type=\"bpsim:ElementParameters\" elementRef=\"_90A843CC-9768-44EE-9610-3AB864EA65A2\" id=\"_6sPDMFEkEeeF7cLzdZ522w\">\n" +
                             "            <bpsim:ControlParameters xsi:type=\"bpsim:ControlParameters\">\n" +
                             "              <bpsim:Probability xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:FloatingParameter value=\"100.0\"/>\n" +
                             "              </bpsim:Probability>\n" +
                             "            </bpsim:ControlParameters>\n" +
                             "          </bpsim:ElementParameters>\n" +
                             "          <bpsim:ElementParameters xsi:type=\"bpsim:ElementParameters\" elementRef=\"_4565A230-3E22-45C9-AD0F-9A3159E15CEB\" id=\"_6sPDMVEkEeeF7cLzdZ522w\">\n" +
                             "            <bpsim:ControlParameters xsi:type=\"bpsim:ControlParameters\">\n" +
                             "              <bpsim:Probability xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:FloatingParameter value=\"100.0\"/>\n" +
                             "              </bpsim:Probability>\n" +
                             "            </bpsim:ControlParameters>\n" +
                             "          </bpsim:ElementParameters>\n" +
                             "          <bpsim:ElementParameters xsi:type=\"bpsim:ElementParameters\" elementRef=\"processStartEvent\" id=\"_6sPDMlEkEeeF7cLzdZ522w\">\n" +
                             "            <bpsim:TimeParameters xsi:type=\"bpsim:TimeParameters\">\n" +
                             "              <bpsim:ProcessingTime xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:UniformDistribution max=\"10.0\" min=\"5.0\"/>\n" +
                             "              </bpsim:ProcessingTime>\n" +
                             "            </bpsim:TimeParameters>\n" +
                             "            <bpsim:ControlParameters xsi:type=\"bpsim:ControlParameters\">\n" +
                             "              <bpsim:Probability xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:FloatingParameter value=\"100.0\"/>\n" +
                             "              </bpsim:Probability>\n" +
                             "            </bpsim:ControlParameters>\n" +
                             "          </bpsim:ElementParameters>\n" +
                             "          <bpsim:ElementParameters xsi:type=\"bpsim:ElementParameters\" elementRef=\"_2346040E-86BD-4794-A7E6-4720414058FF\" id=\"_6sPDM1EkEeeF7cLzdZ522w\">\n" +
                             "            <bpsim:TimeParameters xsi:type=\"bpsim:TimeParameters\">\n" +
                             "              <bpsim:ProcessingTime xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:UniformDistribution max=\"10.0\" min=\"5.0\"/>\n" +
                             "              </bpsim:ProcessingTime>\n" +
                             "            </bpsim:TimeParameters>\n" +
                             "            <bpsim:ResourceParameters xsi:type=\"bpsim:ResourceParameters\">\n" +
                             "              <bpsim:Availability xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:FloatingParameter value=\"8.0\"/>\n" +
                             "              </bpsim:Availability>\n" +
                             "              <bpsim:Quantity xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:FloatingParameter value=\"1.0\"/>\n" +
                             "              </bpsim:Quantity>\n" +
                             "            </bpsim:ResourceParameters>\n" +
                             "            <bpsim:CostParameters xsi:type=\"bpsim:CostParameters\">\n" +
                             "              <bpsim:UnitCost xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:FloatingParameter value=\"0.0\"/>\n" +
                             "              </bpsim:UnitCost>\n" +
                             "            </bpsim:CostParameters>\n" +
                             "          </bpsim:ElementParameters>\n" +
                             "          <bpsim:ElementParameters xsi:type=\"bpsim:ElementParameters\" elementRef=\"_DEDB1C64-835C-4DEC-818A-8C0D8B95FDBC\" id=\"_6sPDNFEkEeeF7cLzdZ522w\">\n" +
                             "            <bpsim:TimeParameters xsi:type=\"bpsim:TimeParameters\">\n" +
                             "              <bpsim:ProcessingTime xsi:type=\"bpsim:Parameter\">\n" +
                             "                <bpsim:UniformDistribution max=\"10.0\" min=\"5.0\"/>\n" +
                             "              </bpsim:ProcessingTime>\n" +
                             "            </bpsim:TimeParameters>\n" +
                             "          </bpsim:ElementParameters>\n" +
                             "        </bpsim:Scenario>\n" +
                             "      </bpsim:BPSimData>\n" +
                             "    </bpmn2:extensionElements>\n" +
                             "    <bpmn2:source>_6sPDIFEkEeeF7cLzdZ522w</bpmn2:source>\n" +
                             "    <bpmn2:target>_6sPDIFEkEeeF7cLzdZ522w</bpmn2:target>\n" +
                             "  </bpmn2:relationship>\n" +
                             "</bpmn2:definitions>\n",
                     servlet.getRetData());
    }
}
