/**
 * 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;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.hadoop.hdfs.server.namenode.StreamFile;
import org.junit.Test;

public class TestByteRangeInputStream {
public static class MockHttpURLConnection extends HttpURLConnection {
  public MockHttpURLConnection(URL u) {
    super(u);
  }
  
  @Override
  public boolean usingProxy(){
    return false;
  }
  
  @Override
  public void disconnect() {
  }
  
  @Override
  public void connect() {
  }
  
  @Override
  public InputStream getInputStream() throws IOException {
    return new ByteArrayInputStream("asdf".getBytes());
  } 

  @Override
  public URL getURL() {
    URL u = null;
    try {
      u = new URL("http://resolvedurl/");
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    return u;
  }
  
  @Override
  public int getResponseCode() {
    if (responseCode != -1) {
      return responseCode;
    } else {
      if (getRequestProperty("Range") == null) {
        return 200;
      } else {
        return 206;
      }
    }
  }

  public void setResponseCode(int resCode) {
    responseCode = resCode;
  }
  
  @Override
  public String getHeaderField(String field) {
    return (field.equalsIgnoreCase(StreamFile.CONTENT_LENGTH)) ? "65535" : null;
  }
}
  
  @Test
  public void testByteRange() throws IOException {
    HftpFileSystem.RangeHeaderUrlOpener ospy = spy(
        new HftpFileSystem.RangeHeaderUrlOpener(new URL("http://test/")));
    doReturn(new MockHttpURLConnection(ospy.getURL())).when(ospy)
        .openConnection();
    HftpFileSystem.RangeHeaderUrlOpener rspy = spy(
        new HftpFileSystem.RangeHeaderUrlOpener((URL) null));
    doReturn(new MockHttpURLConnection(rspy.getURL())).when(rspy)
        .openConnection();
    ByteRangeInputStream is = new HftpFileSystem.RangeHeaderInputStream(ospy, rspy);

    assertEquals("getPos wrong", 0, is.getPos());

    is.read();

    assertNull("Initial call made incorrectly (Range Check)", ospy
        .openConnection().getRequestProperty("Range"));

    assertEquals("getPos should be 1 after reading one byte", 1, is.getPos());

    is.read();

    assertEquals("getPos should be 2 after reading two bytes", 2, is.getPos());

    // No additional connections should have been made (no seek)

    rspy.setURL(new URL("http://resolvedurl/"));

    is.seek(100);
    is.read();

    assertEquals("Seek to 100 bytes made incorrectly (Range Check)",
        "bytes=100-", rspy.openConnection().getRequestProperty("Range"));

    assertEquals("getPos should be 101 after reading one byte", 101,
        is.getPos());

    verify(rspy, times(2)).openConnection();

    is.seek(101);
    is.read();

    verify(rspy, times(2)).openConnection();

    // Seek to 101 should not result in another request"

    is.seek(2500);
    is.read();

    assertEquals("Seek to 2500 bytes made incorrectly (Range Check)",
        "bytes=2500-", rspy.openConnection().getRequestProperty("Range"));

    ((MockHttpURLConnection) rspy.openConnection()).setResponseCode(200);
    is.seek(500);
    
    try {
      is.read();
      fail("Exception should be thrown when 200 response is given "
           + "but 206 is expected");
    } catch (IOException e) {
      assertEquals("Should fail because incorrect response code was sent",
                   "HTTP_PARTIAL expected, received 200", e.getMessage());
    }

    ((MockHttpURLConnection) rspy.openConnection()).setResponseCode(206);
    is.seek(0);

    try {
      is.read();
      fail("Exception should be thrown when 206 response is given "
           + "but 200 is expected");
    } catch (IOException e) {
      assertEquals("Should fail because incorrect response code was sent",
                   "HTTP_OK expected, received 206", e.getMessage());
    }
  }
  
  @Test
  public void testPropagatedClose() throws IOException {
    ByteRangeInputStream brs = spy(
        new HftpFileSystem.RangeHeaderInputStream(new URL("http://test/")));
    
    InputStream mockStream = mock(InputStream.class);
    doReturn(mockStream).when(brs).openInputStream();

    int brisOpens = 0;
    int brisCloses = 0;
    int isCloses = 0;
    
    // first open, shouldn't close underlying stream
    brs.getInputStream();
    verify(brs, times(++brisOpens)).openInputStream();
    verify(brs, times(brisCloses)).close();
    verify(mockStream, times(isCloses)).close();
    
    // stream is open, shouldn't close underlying stream
    brs.getInputStream();
    verify(brs, times(brisOpens)).openInputStream();
    verify(brs, times(brisCloses)).close();
    verify(mockStream, times(isCloses)).close();
    
    // seek forces a reopen, should close underlying stream
    brs.seek(1);
    brs.getInputStream();
    verify(brs, times(++brisOpens)).openInputStream();
    verify(brs, times(brisCloses)).close();
    verify(mockStream, times(++isCloses)).close();

    // verify that the underlying stream isn't closed after a seek
    // ie. the state was correctly updated
    brs.getInputStream();
    verify(brs, times(brisOpens)).openInputStream();
    verify(brs, times(brisCloses)).close();
    verify(mockStream, times(isCloses)).close();

    // seeking to same location should be a no-op
    brs.seek(1);
    brs.getInputStream();
    verify(brs, times(brisOpens)).openInputStream();
    verify(brs, times(brisCloses)).close();
    verify(mockStream, times(isCloses)).close();

    // close should of course close
    brs.close();
    verify(brs, times(++brisCloses)).close();
    verify(mockStream, times(++isCloses)).close();
    
    // it's already closed, underlying stream should not close
    brs.close();
    verify(brs, times(++brisCloses)).close();
    verify(mockStream, times(isCloses)).close();
    
    // it's closed, don't reopen it
    boolean errored = false;
    try {
      brs.getInputStream();
    } catch (IOException e) {
      errored = true;
      assertEquals("Stream closed", e.getMessage());
    } finally {
      assertTrue("Read a closed steam", errored);
    }
    verify(brs, times(brisOpens)).openInputStream();
    verify(brs, times(brisCloses)).close();
    verify(mockStream, times(isCloses)).close();
  }
}
