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

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.mapred.Reporter;

import org.apache.hadoop.raid.protocol.PolicyInfo;

public class TestDirectoryTraversal extends TestCase {
  final static Log LOG = LogFactory.getLog(
                            "org.apache.hadoop.raid.TestDirectoryTraversal");
  final static String TEST_DIR = new File(System.getProperty("test.build.data",
      "build/contrib/raid/test/data")).getAbsolutePath();

  MiniDFSCluster dfs = null;
  FileSystem fs = null;
  Configuration conf = null;

  /**
   * Test basic enumeration.
   */
  public void testEnumeration() throws IOException {
    mySetup();

    try {
      Path topDir = new Path(TEST_DIR + "/testenumeration");

      createTestTree(topDir);

      LOG.info("Enumerating files");
      List<FileStatus> startPaths = new LinkedList<FileStatus>();
      startPaths.add(fs.getFileStatus(topDir));
      DirectoryTraversal dt = new DirectoryTraversal(fs, startPaths, 2);

      List<FileStatus> selected = new LinkedList<FileStatus>();
      while (true) {
        FileStatus f = dt.getNextFile();
        if (f == null) break;
        assertEquals(false, f.isDir());
        LOG.info(f.getPath());
        selected.add(f);
      }
      assertEquals(5, selected.size());

      LOG.info("Enumerating directories");
      startPaths.clear();
      startPaths.add(fs.getFileStatus(topDir));
      dt = new DirectoryTraversal(fs, startPaths);
      selected.clear();
      while (true) {
        FileStatus dir = dt.getNextDirectory();
        if (dir == null) break;
        assertEquals(true, dir.isDir());
        LOG.info(dir.getPath());
        selected.add(dir);
      }
      assertEquals(4, selected.size());
    } finally {
      myTearDown();
    }
  }

  public void testSuspension() throws IOException {
    LOG.info("Starting testSuspension");
    mySetup();

    try {
      Path topDir = new Path(TEST_DIR + "/testenumeration");

      createTestTree(topDir);

      String top = topDir.toString();
      List<FileStatus> startPaths = new LinkedList<FileStatus>();
      startPaths.add(fs.getFileStatus(new Path(top + "/a")));
      startPaths.add(fs.getFileStatus(new Path(top + "/b")));
      DirectoryTraversal dt = new DirectoryTraversal(fs, startPaths);

      int limit = 2;
      short targetRepl = 1;
      Path raid = new Path("/raid");
      DirectoryTraversal.FileFilter filter =
        new RaidFilter.TimeBasedFilter(conf,
          RaidNode.xorDestinationPath(conf), 1, System.currentTimeMillis(), 0);
      List<FileStatus> selected = dt.getFilteredFiles(filter, limit);
      for (FileStatus f: selected) {
        LOG.info(f.getPath());
      }
      assertEquals(limit, selected.size());

      selected = dt.getFilteredFiles(filter, limit);
      for (FileStatus f: selected) {
        LOG.info(f.getPath());
      }
      assertEquals(limit, selected.size());
    } finally {
      myTearDown();
    }
  }

  public void testFileFilter() throws IOException {
    mySetup();

    try {
      Path topDir = new Path(TEST_DIR + "/testFileFilter");
      int targetRepl = 1;
      createTestTree(topDir);
      Path file = new Path(topDir.toString() + "/a/f1");
      FileStatus stat = fs.getFileStatus(file);
      PolicyInfo info = new PolicyInfo("testFileFilter", conf);
      info.setSrcPath(topDir.toString());
      info.setErasureCode("rs");
      info.setDescription("test policy");
      info.setProperty("targetReplication", "1");
      info.setProperty("metaReplication", "1");

      DirectoryTraversal.FileFilter timeBasedXORFilter =
        new RaidFilter.TimeBasedFilter(conf,
          RaidNode.xorDestinationPath(conf), targetRepl,
            System.currentTimeMillis(), 0);
      DirectoryTraversal.FileFilter timeBasedRSFilter =
        new RaidFilter.TimeBasedFilter(conf,
          RaidNode.rsDestinationPath(conf), targetRepl,
            System.currentTimeMillis(), 0);
      DirectoryTraversal.FileFilter preferenceForRSFilter =
        new RaidFilter.PreferenceFilter(
          conf, RaidNode.rsDestinationPath(conf),
          RaidNode.xorDestinationPath(conf), 1, System.currentTimeMillis(), 0);

      assertTrue(timeBasedXORFilter.check(stat));
      assertTrue(timeBasedRSFilter.check(stat));
      assertTrue(preferenceForRSFilter.check(stat));

      RaidNode.doRaid(
        conf, info, stat, new RaidNode.Statistics(), Reporter.NULL);

      assertTrue(timeBasedXORFilter.check(stat));
      assertFalse(timeBasedRSFilter.check(stat));
      assertFalse(preferenceForRSFilter.check(stat));
    } finally {
      myTearDown();
    }
  }

  /**
   * Creates a test directory tree.
   *            top
   *           / | \
   *          /  |  f5
   *         a   b___
   *        / \  |\  \
   *       f1 f2 f3f4 c
   */
  private void createTestTree(Path topDir) throws IOException {
    String top = topDir.toString();
    fs.delete(topDir, true);

    fs.mkdirs(topDir);
    fs.create(new Path(top + "/f5")).close();

    fs.mkdirs(new Path(top + "/a"));
    createTestFile(new Path(top + "/a/f1"));
    createTestFile(new Path(top + "/a/f2"));

    fs.mkdirs(new Path(top + "/b"));
    fs.mkdirs(new Path(top + "/b/c"));
    createTestFile(new Path(top + "/b/f3"));
    createTestFile(new Path(top + "/b/f4"));
  }

  private void createTestFile(Path file) throws IOException {
    long blockSize = 8192;
    byte[] bytes = new byte[(int)blockSize];
    FSDataOutputStream stm = fs.create(file, false, 4096, (short)1, blockSize);
    stm.write(bytes);
    stm.write(bytes);
    stm.write(bytes);
    stm.close();
    FileStatus stat = fs.getFileStatus(file);
    assertEquals(blockSize, stat.getBlockSize());
  }

  private void mySetup() throws IOException {
    conf = new Configuration();
    dfs = new MiniDFSCluster(conf, 6, true, null);
    dfs.waitActive();
    fs = dfs.getFileSystem();
  }

  private void myTearDown() {
    if (dfs != null) { dfs.shutdown(); }
  }
}
