/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.sling.servlets.get.impl.helpers;

import static org.junit.Assert.assertEquals;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
import javax.servlet.ServletContext;
import junitx.util.PrivateAccessor;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.junit.Test;
import org.mockito.Mockito;

public class StreamRendererServletTest {

    @Test
    public void testCopyRange() throws IOException {
        runTests(1234);
        runTests(4321);
    }

    @Test
    public void testResultingLength() throws IOException {
        final ByteArrayInputStream in = new ByteArrayInputStream("12345678".getBytes());
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        StreamRendererServlet.staticCopyRange(in, out, 2, 4);
        final String result = out.toString();
        assertEquals(2, result.length());
        assertEquals("34", result);
    }
    
    private void runTests(int randomSeed) throws IOException {
        final Random random = new Random(randomSeed);
        assertCopyRange(random, StreamRendererServlet.IO_BUFFER_SIZE * 2 + 42);
        assertCopyRange(random, StreamRendererServlet.IO_BUFFER_SIZE * 3);
        assertCopyRange(random, StreamRendererServlet.IO_BUFFER_SIZE);
        assertCopyRange(random, StreamRendererServlet.IO_BUFFER_SIZE - 1);
        assertCopyRange(random, random.nextInt(StreamRendererServlet.IO_BUFFER_SIZE));
        assertCopyRange(random, 42);
        assertCopyRange(random, 1);
    }

    private void assertCopyRange(Random random, int bufferSize) throws IOException {

        // generate some random test data
        final byte[] expected = new byte[bufferSize];
        random.nextBytes(expected);

        // Check some simple cases ...
        assertCopyRange(expected, 0, 0);
        assertCopyRange(expected, 0, 1);
        assertCopyRange(expected, 0, expected.length);

        // ... and a few randomly selected ones
        final int n = random.nextInt(100);
        for (int i = 0; i < n; i++) {
            final int a = random.nextInt(expected.length);
            final int b = random.nextInt(expected.length);
            assertCopyRange(expected, Math.min(a, b), Math.max(a, b));
        }
    }

    private void assertCopyRange(byte[] expected, int a, int b) throws IOException {
        assertCopyRange(expected, new ByteArrayInputStream(expected), a, b);
        // with BufferedInputStream
        assertCopyRange(expected, new BufferedInputStream(new ByteArrayInputStream(expected)), a, b);
        // without available()
        assertCopyRange(expected, new ByteArrayInputStream(expected) {
            @Override
            public synchronized int available() {
                return 0;
            }
        }, a, b);
        // with BufferedInputStream and without available()
        assertCopyRange(expected, new BufferedInputStream(new ByteArrayInputStream(expected) {
            @Override
            public synchronized int available() {
                return 0;
            }
        }), a, b);
        // with an input stream that does not return everything in read()
        assertCopyRange(expected, new ByteArrayInputStream(expected) {
            @Override
            public synchronized int read(byte[] b, int off, int len) {
                // allow maximum of 10
                if (len > 10) {
                    len = 10;
                }
                return super.read(b, off, len);
            }
        }, a, b);
    }

    private void assertCopyRange(
            byte[] expected, InputStream input, int a, int b) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        StreamRendererServlet.staticCopyRange(input, output, a, b);

        byte[] actual = output.toByteArray();
        assertEquals(b - a, actual.length);
        for (int i = a; i < b; i++) {
            assertEquals(expected[i], actual[i - a]);
        }
    }
    
    @Test
    public void test_setHeaders() throws Throwable {
        
        final Resource resource = Mockito.mock(Resource.class);
        final SlingHttpServletResponse response = Mockito.mock(SlingHttpServletResponse .class);
        final ResourceMetadata meta = Mockito.mock(ResourceMetadata.class);
        final ServletContext sc = Mockito.mock(ServletContext.class);
        
        StreamRendererServlet streamRendererServlet = new StreamRendererServlet(true,new String []{"/"}) {
            @Override
            public ServletContext getServletContext() {
                return sc;
            }
        };        

        Mockito.when(resource.getResourceMetadata()).thenReturn(meta);
        PrivateAccessor.invoke(streamRendererServlet, "setHeaders", new Class[]{Resource.class, SlingHttpServletResponse.class}, new Object[]{resource, response});
        Mockito.verify(response,Mockito.times(1)).setContentType("application/octet-stream");
    }
}
