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

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;

import junit.framework.TestCase;

import org.apache.hadoop.conf.Configuration;

/**
 * Testing the correctness of FileSystem.getFileBlockLocations.
 */
public class TestGetFileBlockLocations extends TestCase {
  private static String TEST_ROOT_DIR =
      System.getProperty("test.build.data", "/tmp/testGetFileBlockLocations");
  private static final int FileLength = 4 * 1024 * 1024; // 4MB
  private Configuration conf;
  private Path path;
  private FileSystem fs;
  private Random random;

  /**
   * @see TestCase#setUp()
   */
  @Override
  protected void setUp() throws IOException {
    conf = new Configuration();
    Path rootPath = new Path(TEST_ROOT_DIR);
    path = new Path(rootPath, "TestGetFileBlockLocations");
    fs = rootPath.getFileSystem(conf);
    FSDataOutputStream fsdos = fs.create(path, true);
    byte[] buffer = new byte[1024];
    while (fsdos.getPos() < FileLength) {
      fsdos.write(buffer);
    }
    fsdos.close();
    random = new Random(System.nanoTime());
  }

  private void oneTest(int offBegin, int offEnd, FileStatus status)
      throws IOException {
    if (offBegin > offEnd) {
      int tmp = offBegin;
      offBegin = offEnd;
      offEnd = tmp;
    }
    BlockLocation[] locations =
        fs.getFileBlockLocations(status, offBegin, offEnd - offBegin);
    if (offBegin < status.getLen()) {
      Arrays.sort(locations, new Comparator<BlockLocation>() {

        @Override
        public int compare(BlockLocation arg0, BlockLocation arg1) {
          long cmprv = arg0.getOffset() - arg1.getOffset();
          if (cmprv < 0) return -1;
          if (cmprv > 0) return 1;
          cmprv = arg0.getLength() - arg1.getLength();
          if (cmprv < 0) return -1;
          if (cmprv > 0) return 1;
          return 0;
        }

      });
      offBegin = (int) Math.min(offBegin, status.getLen() - 1);
      offEnd = (int) Math.min(offEnd, status.getLen());
      BlockLocation first = locations[0];
      BlockLocation last = locations[locations.length - 1];
      assertTrue(first.getOffset() <= offBegin);
      assertTrue(offEnd <= last.getOffset() + last.getLength());
    } else {
      assertTrue(locations.length == 0);
    }
  }
  /**
   * @see TestCase#tearDown()
   */
  @Override
  protected void tearDown() throws IOException {
    fs.delete(path, true);
    fs.close();
  }

  public void testFailureNegativeParameters() throws IOException {
    FileStatus status = fs.getFileStatus(path);
    try {
      BlockLocation[] locations = fs.getFileBlockLocations(status, -1, 100);
      fail("Expecting exception being throw");
    } catch (IllegalArgumentException e) {

    }

    try {
      BlockLocation[] locations = fs.getFileBlockLocations(status, 100, -1);
      fail("Expecting exception being throw");
    } catch (IllegalArgumentException e) {

    }
  }

  public void testGetFileBlockLocations1() throws IOException {
    FileStatus status = fs.getFileStatus(path);
    oneTest(0, (int) status.getLen(), status);
    oneTest(0, (int) status.getLen() * 2, status);
    oneTest((int) status.getLen() * 2, (int) status.getLen() * 4, status);
    oneTest((int) status.getLen() / 2, (int) status.getLen() * 3, status);
    oneTest((int) status.getLen(), (int) status.getLen() * 2, status);
    for (int i = 0; i < 10; ++i) {
      oneTest((int) status.getLen() * i / 10, (int) status.getLen() * (i + 1)
          / 10, status);
    }
  }

  public void testGetFileBlockLocations2() throws IOException {
    FileStatus status = fs.getFileStatus(path);
    for (int i = 0; i < 1000; ++i) {
      int offBegin = random.nextInt((int) (2 * status.getLen()));
      int offEnd = random.nextInt((int) (2 * status.getLen()));
      oneTest(offBegin, offEnd, status);
    }
  }
}
