package com.vitalize.atg.dynadmin;

import atg.adapter.gsa.GSAAdminServlet;
import atg.adapter.gsa.GSARepository;
import atg.nucleus.Nucleus;
import atg.nucleus.logging.ApplicationLogging;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.TransactionManager;
import java.io.IOException;
import java.util.Scanner;

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.*;


public class SwoleGSAAdminServletTest {

    static String EXPECTED_SCRIPT = new Scanner(
            GSAAdminServlet.class.getClassLoader().getResourceAsStream("com/vitalize/atg/dynadmin/SwoleGSAAdminServlet.js"),
            "UTF-8"
        )
        .useDelimiter("\\A")
        .next();

    @Mock
    GSARepository mockGSARepo;

    @Mock
    ApplicationLogging mockLogger;

    @Mock
    Nucleus mockNucleus;

    @Mock
    TransactionManager mockTxManager;

    @Mock
    HttpServletRequest mockRequest;

    @Mock
    HttpServletResponse mockResponse;

    @Mock
    ServletOutputStream mockOutputStream;


    @Before
    public void setUp(){
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testPrintAdminRQLBoxNotPresent() throws ServletException, IOException {

        SwoleGSAAdminServlet subject = new SwoleGSAAdminServlet(
            mockGSARepo,
            mockLogger,
            mockNucleus,
            mockTxManager
        ){
            //This is a bit tricky to test because we are relying on the stubs impl for super class
            //but that doesn't actually do anything...anyone have a better idea?
            @Override
            protected void printAdminInternal(HttpServletRequest pRequest, HttpServletResponse pResponse, ServletOutputStream pOut) throws ServletException, IOException {

                //instead of calling super pretend i did
                pOut.println("not the text we care about");
            }
        };


        subject.printAdmin(
            mockRequest,
            mockResponse,
            mockOutputStream
        );

        //Make sure nothing extra was added
        verify(mockOutputStream, times(1)).println(anyString());

    }



    @Test
    public void testPrintAdminRQLBoxPresent() throws ServletException, IOException {

        String[] descriptors = new String[]{
            "dogs",
            "cats"
        };

        when(mockGSARepo.getItemDescriptorNames())
            .thenReturn(descriptors);

        SwoleGSAAdminServlet subject = new SwoleGSAAdminServlet(
            mockGSARepo,
            mockLogger,
            mockNucleus,
            mockTxManager
        ){
            //This is a bit tricky to test because we are relying on the stubs impl for super class
            //but that doesn't actually do anything...anyone have a better idea?
            @Override
            protected void printAdminInternal(HttpServletRequest req, HttpServletResponse res, ServletOutputStream out) throws ServletException, IOException {

                //instead of calling super pretend i did
                out.println("<p><textarea rows=\"12\" cols=\"80\" name=\"xmltext\">");

                out.println("some other content");
            }
        };


        subject.printAdmin(
            mockRequest,
            mockResponse,
            mockOutputStream
        );

        //Make sure the better rql box is output
        verify(mockOutputStream, times(1)).println("<p><textarea rows=\"20\" cols=\"160\" name=\"xmltext\">");

        for(String d: descriptors) {
            //make sure all the descriptors are out there
            verify(mockOutputStream, times(1)).println("<option>" + d + "</option>");
        }

        assertThat(
            EXPECTED_SCRIPT,
            not(
                isEmptyOrNullString()
            )
        );

        verify(mockOutputStream, times(1)).println(EXPECTED_SCRIPT);

        //make sure we ouput the RQL help
        verify(mockOutputStream, times(1)).println("<a href=\"https://docs.oracle.com/cd/E24152_01/Platform.10-1/ATGRepositoryGuide/html/s0305rqloverview01.html\" target=\"_blank\">Y U FORGET RQL?</a>");


        verify(mockOutputStream, times(1)).println("some other content");
    }



}

@@ -293,16 +293,100 @@
 tations;
+%0Aimport org.mockito.invocation.InvocationOnMock;%0Aimport org.mockito.stubbing.Answer;
 %0A%0Aimport
@@ -2693,16 +2693,419 @@
     %7D;%0A%0A
+        final StringBuilder allOutputBuilder = new StringBuilder();%0A%0A        doAnswer(%0A            new Answer%3CObject%3E() %7B%0A                public Object answer(InvocationOnMock invocation) throws Throwable %7B%0A                    allOutputBuilder.append(invocation.getArguments()%5B0%5D);%0A                    return null;%0A                %7D%0A            %7D%0A        ).when(mockOutputStream).println(anyString());%0A%0A
         
@@ -4064,32 +4064,35 @@
         );%0A%0A
+%0A%0A%0A
         
 //Make sure 
@@ -4083,99 +4083,126 @@
     
-//Make sure the better rql box is output%0A        verify(mockOutputStream, times(1)).println
+String allOutput = allOutputBuilder.toString();%0A%0A        assertThat(%0A            allOutput,%0A            containsString
 (%22%3Cp
@@ -4248,33 +4248,44 @@
 e=%5C%22xmltext%5C%22%3E%22)
-;
+%0A        );%0A
 %0A%0A        for(St
@@ -4323,108 +4323,77 @@
     
-//make sure all the descriptors are out there%0A            verify(mockOutputStream, times(1)).println
+assertThat(%0A                allOutput,%0A                containsString
 (%22%3Co
@@ -4418,16 +4418,30 @@
 ption%3E%22)
+%0A            )
 ;%0A      
@@ -4587,162 +4587,169 @@
     
-verify(mockOutputStream, times(1)).println(EXPECTED_SCRIPT);%0A%0A        //make sure we ouput the RQL help%0A        verify(mockOutputStream, times(1)).println
+assertThat(%0A            allOutput,%0A            containsString(EXPECTED_SCRIPT)%0A        );%0A%0A%0A        assertThat(%0A            allOutput,%0A            containsString
 (%22%3Ca
@@ -4896,16 +4896,26 @@
 L?%3C/a%3E%22)
+%0A        )
 ;%0A%0A%0A    
@@ -4980,23 +4980,24 @@
  content%22);%0A
+%0A
     %7D%0A%0A%0A%0A%7D%0A

fix tests given html content is all one big blob