/**
 * 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.hadoop.hdfs.server.namenode;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.fs.FSInputStream;
import org.apache.hadoop.hdfs.server.namenode.StreamFile;
import org.mortbay.jetty.InclusiveByteRange;
import static org.junit.Assert.*;

/*
  Mock input stream class that always outputs the current position of the stream
*/
class MockFSInputStream extends FSInputStream {
  long currentPos = 0;
  public int read() throws IOException {
    return (int)(currentPos++);
  }

  public void close() throws IOException {
  }

  public void seek(long pos) throws IOException {
    currentPos = pos;
  }
  
  public long getPos() throws IOException {
    return currentPos;
  }
  
  public boolean seekToNewSource(long targetPos) throws IOException {
    return false;
  }
}


class MockHttpServletResponse implements HttpServletResponse {

  private int status = -1;
  
  public MockHttpServletResponse() {
  }
  
  public int getStatus() {
    return status;
  }
  
  
  public void setStatus(int sc) {
    status = sc;
  }
  
  @SuppressWarnings("deprecation")
  public void setStatus(int sc, java.lang.String sm) {
  }
  
  public void addIntHeader(String name, int value) {
  }

  public void setIntHeader(String name, int value) { 
  }
  
  public void addHeader(String name, String value) {
  }

  public void setHeader(String name, String value) {
  }
  
  public void addDateHeader(java.lang.String name, long date) {
  }
  
  public void setDateHeader(java.lang.String name, long date) {
  }

  public void sendRedirect(java.lang.String location) { 
  }
  
  public void sendError(int e) {
  }
  
  public void sendError(int a, java.lang.String b) {
  }
  
  public String encodeRedirectUrl(java.lang.String a) {
    return null;
  }
  
  public String encodeUrl(java.lang.String url) {
    return null;
  }
  
  public String encodeRedirectURL(java.lang.String url) {
    return null;
  }
  
  public String encodeURL(java.lang.String url) {
    return null;
  }
  
  public boolean containsHeader(java.lang.String name) {
    return false;
  }
  
  public void addCookie(javax.servlet.http.Cookie cookie) {
  }
  
  public java.util.Locale getLocale() {
    return null;
  }
  
  public void setLocale(java.util.Locale loc) {
  }
  
  public void reset() {
  }
  
  public boolean isCommitted() {
    return false;
  }
  
  public void resetBuffer() {
  }
  
  public void flushBuffer() {
  }
  
  public int getBufferSize() {
    return 0;
  }
  
  public void setBufferSize(int size) {
  }
  
  public void setContentType(java.lang.String type) {
  }
  
  public void setContentLength(int len) {
  }
  
  public void setCharacterEncoding(java.lang.String charset) {
  }
  
  public java.io.PrintWriter getWriter() {
    return null;
  }
  
  public javax.servlet.ServletOutputStream getOutputStream() {
    return null;
  }
  
  public java.lang.String getContentType() {
    return null;
  }
  
  public java.lang.String getCharacterEncoding() {
    return null;
  }
}



public class TestStreamFile extends TestCase {
  
  private static final Log LOG =  LogFactory.getLog(TestStreamFile.class);

  // return an array matching the output of mockfsinputstream
  private static byte[] getOutputArray(int start, int count) {
    byte[] a = new byte[count];
    
    for (int i = 0; i < count; i++) {
      a[i] = (byte)(start+i);
    }

    return a;
  }
  
  public void testWriteTo() throws IOException, InterruptedException {

    FSInputStream fsin = new MockFSInputStream();
    ByteArrayOutputStream os = new ByteArrayOutputStream();

    // new int[]{s_1, c_1, s_2, c_2, ..., s_n, c_n} means to test
    // reading c_i bytes starting at s_i
    int[] pairs = new int[]{ 0, 10000,
                             50, 100,
                             50, 6000,
                             1000, 2000,
                             0, 1,
                             0, 0,
                             5000, 0,
                            };
                            
    assertTrue("Pairs array must be even", pairs.length % 2 == 0);
    
    for (int i = 0; i < pairs.length; i+=2) {
      StreamFile.writeTo(fsin, os, pairs[i], pairs[i+1]);
      assertArrayEquals("Reading " + pairs[i+1]
                        + " bytes from offset " + pairs[i],
                        getOutputArray(pairs[i], pairs[i+1]),
                        os.toByteArray());
      os.reset();
    }
    
  }
  
  private List strToRanges(String s, int contentLength) {
    List<String> l = Arrays.asList(new String[]{"bytes="+s});
    Enumeration e = (new Vector<String>(l)).elements();
    return InclusiveByteRange.satisfiableRanges(e, contentLength);
  }
  
  public void testSendPartialData() throws IOException, InterruptedException {
    FSInputStream in = new MockFSInputStream();
    ByteArrayOutputStream os = new ByteArrayOutputStream();

    // test if multiple ranges, then 416
    { 
      List ranges = strToRanges("0-,10-300", 500);
      MockHttpServletResponse response = new MockHttpServletResponse();
      StreamFile.sendPartialData(in, os, response, 500, ranges);
      assertEquals("Multiple ranges should result in a 416 error",
                   416, response.getStatus());
    }
                              
    // test if no ranges, then 416
    { 
      os.reset();
      MockHttpServletResponse response = new MockHttpServletResponse();
      StreamFile.sendPartialData(in, os, response, 500, null);
      assertEquals("No ranges should result in a 416 error",
                   416, response.getStatus());
    }

    // test if invalid single range (out of bounds), then 416
    { 
      List ranges = strToRanges("600-800", 500);
      MockHttpServletResponse response = new MockHttpServletResponse();
      StreamFile.sendPartialData(in, os, response, 500, ranges);
      assertEquals("Single (but invalid) range should result in a 416",
                   416, response.getStatus());
    }

      
    // test if one (valid) range, then 206
    { 
      List ranges = strToRanges("100-300", 500);
      MockHttpServletResponse response = new MockHttpServletResponse();
      StreamFile.sendPartialData(in, os, response, 500, ranges);
      assertEquals("Single (valid) range should result in a 206",
                   206, response.getStatus());
      assertArrayEquals("Byte range from 100-300",
                        getOutputArray(100, 201),
                        os.toByteArray());
    }
    
  }
}
