/**
 * 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 static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.util.EnumSet;
import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.Options.ChecksumOpt;
import org.apache.hadoop.fs.Options.CreateOpts;
import org.apache.hadoop.fs.Options.Rename;
import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.util.Progressable;
import org.junit.BeforeClass;
import org.junit.Test;

public class TestFilterFileSystem {

  private static final Log LOG = FileSystem.LOG;
  private static final Configuration conf = new Configuration();

  @BeforeClass
  public static void setup() {
    conf.set("fs.flfs.impl", FilterLocalFileSystem.class.getName());
    conf.setBoolean("fs.flfs.impl.disable.cache", true);
    conf.setBoolean("fs.file.impl.disable.cache", true);
  }
  
  public static class DontCheck {
    public BlockLocation[] getFileBlockLocations(Path p, 
        long start, long len) { return null; }
    public FsServerDefaults getServerDefaults() { return null; }
    public long getLength(Path f) { return 0; }
    public FSDataOutputStream append(Path f) { return null; }
    public FSDataOutputStream append(Path f, int bufferSize) { return null; }
    public void rename(final Path src, final Path dst, final Rename... options) { }
    public boolean exists(Path f) { return false; }
    public boolean isDirectory(Path f) { return false; }
    public boolean isFile(Path f) { return false; }
    public boolean createNewFile(Path f) { return false; }
    public FSDataOutputStream createNonRecursive(Path f,
        boolean overwrite,
        int bufferSize, short replication, long blockSize,
        Progressable progress) throws IOException {
      return null;
    }
    public FSDataOutputStream createNonRecursive(Path f, FsPermission permission,
        boolean overwrite, int bufferSize, short replication, long blockSize,
        Progressable progress) throws IOException {
      return null;
    }
    public FSDataOutputStream createNonRecursive(Path f, FsPermission permission,
            EnumSet<CreateFlag> flags, int bufferSize, short replication, long blockSize,
            Progressable progress) throws IOException {
      return null;
    }
    public FSDataOutputStream createNonRecursive(Path f, FsPermission permission,
            EnumSet<CreateFlag> flags, int bufferSize, short replication, long blockSize,
            Progressable progress, ChecksumOpt checksumOpt) throws IOException {
      return null;
    }
    public boolean mkdirs(Path f) { return false; }
    public FSDataInputStream open(Path f) { return null; }
    public FSDataOutputStream create(Path f) { return null; }
    public FSDataOutputStream create(Path f, boolean overwrite) { return null; }
    public FSDataOutputStream create(Path f, Progressable progress) {
      return null;
    }
    public FSDataOutputStream create(Path f, short replication) {
      return null;
    }
    public FSDataOutputStream create(Path f, short replication, 
        Progressable progress) {
      return null;
    }
    public FSDataOutputStream create(Path f, 
        boolean overwrite,
        int bufferSize) {
      return null;
    }
    public FSDataOutputStream create(Path f, 
        boolean overwrite,
        int bufferSize,
        Progressable progress) {
      return null;
    }
    public FSDataOutputStream create(Path f, 
        boolean overwrite,
        int bufferSize,
        short replication,
        long blockSize) {
      return null;
    }
    public FSDataOutputStream create(Path f,
        boolean overwrite,
        int bufferSize,
        short replication,
        long blockSize,
        Progressable progress) {
      return null;
    }
    public FSDataOutputStream create(Path f,
        FsPermission permission,
        boolean overwrite,
        int bufferSize,
        short replication,
        long blockSize,
        Progressable progress) {
      return null;
    }
    public FSDataOutputStream create(Path f,
        FsPermission permission,
        EnumSet<CreateFlag> flags,
        int bufferSize,
        short replication,
        long blockSize,
        Progressable progress) throws IOException {
      return null;
    }
    public FSDataOutputStream create(Path f,
        FsPermission permission,
        EnumSet<CreateFlag> flags,
        int bufferSize,
        short replication,
        long blockSize,
        Progressable progress,
        ChecksumOpt checksumOpt) throws IOException {
      return null;
    }
    public String getName() { return null; }
    public boolean delete(Path f) { return false; }
    public short getReplication(Path src) { return 0 ; }
    public void processDeleteOnExit() { }
    public ContentSummary getContentSummary(Path f) { return null; }
    public FsStatus getStatus() { return null; }
    public FileStatus[] listStatus(Path f, PathFilter filter) { return null; }
    public FileStatus[] listStatus(Path[] files) { return null; }
    public FileStatus[] listStatus(Path[] files, PathFilter filter) { return null; }
    public FileStatus[] globStatus(Path pathPattern) { return null; }
    public FileStatus[] globStatus(Path pathPattern, PathFilter filter) {
      return null;
    }
    public Iterator<LocatedFileStatus> listFiles(
        final Path path, final boolean isRecursive) {
      return null;
    }
    public Iterator<LocatedFileStatus> listLocatedStatus(Path f) {
      return null;
    }
    public Iterator<LocatedFileStatus> listLocatedStatus(Path f,
        final PathFilter filter) {
      return null;
    }
    public void copyFromLocalFile(Path src, Path dst) { }
    public void moveFromLocalFile(Path[] srcs, Path dst) { }
    public void moveFromLocalFile(Path src, Path dst) { }
    public void copyToLocalFile(Path src, Path dst) { }
    public void copyToLocalFile(boolean delSrc, Path src, Path dst, 
            boolean useRawLocalFileSystem) { }
    public void moveToLocalFile(Path src, Path dst) { }
    public long getBlockSize(Path f) { return 0; }
    public FSDataOutputStream primitiveCreate(final Path f,
        final EnumSet<CreateFlag> createFlag,
        CreateOpts... opts) { return null; }
    public void primitiveMkdir(Path f, FsPermission absolutePermission, 
                      boolean createParent) { }
    public int getDefaultPort() { return 0; }
    public String getCanonicalServiceName() { return null; }
    public Token<?> getDelegationToken(String renewer) throws IOException {
      return null;
    }
    public boolean deleteOnExit(Path f) throws IOException {
      return false;
    }
    public boolean cancelDeleteOnExit(Path f) throws IOException {
      return false;
    }
    public Token<?>[] addDelegationTokens(String renewer, Credentials creds)
        throws IOException {
      return null;
    }
    public String getScheme() {
      return "dontcheck";
    }
  }
  
  @Test
  public void testFilterFileSystem() throws Exception {
    for (Method m : FileSystem.class.getDeclaredMethods()) {
      if (Modifier.isStatic(m.getModifiers()))
        continue;
      if (Modifier.isPrivate(m.getModifiers()))
        continue;
      if (Modifier.isFinal(m.getModifiers()))
        continue;
      
      try {
        DontCheck.class.getMethod(m.getName(), m.getParameterTypes());
        LOG.info("Skipping " + m);
      } catch (NoSuchMethodException exc) {
        LOG.info("Testing " + m);
        try{
          FilterFileSystem.class.getDeclaredMethod(m.getName(), m.getParameterTypes());
        }
        catch(NoSuchMethodException exc2){
          LOG.error("FilterFileSystem doesn't implement " + m);
          throw exc2;
        }
      }
    }
  }
  
  @Test
  public void testFilterEmbedInit() throws Exception {
    FileSystem mockFs = createMockFs(false); // no conf = need init
    checkInit(new FilterFileSystem(mockFs), true);
  }

  @Test
  public void testFilterEmbedNoInit() throws Exception {
    FileSystem mockFs = createMockFs(true); // has conf = skip init
    checkInit(new FilterFileSystem(mockFs), false);
  }

  @Test
  public void testLocalEmbedInit() throws Exception {
    FileSystem mockFs = createMockFs(false); // no conf = need init
    checkInit(new LocalFileSystem(mockFs), true);
  }  
  
  @Test
  public void testLocalEmbedNoInit() throws Exception {
    FileSystem mockFs = createMockFs(true); // has conf = skip init
    checkInit(new LocalFileSystem(mockFs), false);
  }
  
  private FileSystem createMockFs(boolean useConf) {
    FileSystem mockFs = mock(FileSystem.class);
    when(mockFs.getUri()).thenReturn(URI.create("mock:/"));
    when(mockFs.getConf()).thenReturn(useConf ? conf : null);
    return mockFs;
  }

  @Test
  public void testGetLocalFsSetsConfs() throws Exception {
    LocalFileSystem lfs = FileSystem.getLocal(conf);
    checkFsConf(lfs, conf, 2);
  }

  @Test
  public void testGetFilterLocalFsSetsConfs() throws Exception {
    FilterFileSystem flfs =
        (FilterFileSystem) FileSystem.get(URI.create("flfs:/"), conf);
    checkFsConf(flfs, conf, 3);
  }

  @Test
  public void testInitLocalFsSetsConfs() throws Exception {
    LocalFileSystem lfs = new LocalFileSystem();
    checkFsConf(lfs, null, 2);
    lfs.initialize(lfs.getUri(), conf);
    checkFsConf(lfs, conf, 2);
  }

  @Test
  public void testInitFilterFsSetsEmbedConf() throws Exception {
    LocalFileSystem lfs = new LocalFileSystem();
    checkFsConf(lfs, null, 2);
    FilterFileSystem ffs = new FilterFileSystem(lfs);
    assertEquals(lfs, ffs.getRawFileSystem());
    checkFsConf(ffs, null, 3);
    ffs.initialize(URI.create("filter:/"), conf);
    checkFsConf(ffs, conf, 3);
  }

  @Test
  public void testInitFilterLocalFsSetsEmbedConf() throws Exception {
    FilterFileSystem flfs = new FilterLocalFileSystem();
    assertEquals(LocalFileSystem.class, flfs.getRawFileSystem().getClass());
    checkFsConf(flfs, null, 3);
    flfs.initialize(URI.create("flfs:/"), conf);
    checkFsConf(flfs, conf, 3);
  }

  @Test
  public void testVerifyChecksumPassthru() {
    FileSystem mockFs = mock(FileSystem.class);
    FileSystem fs = new FilterFileSystem(mockFs);

    fs.setVerifyChecksum(false);
    verify(mockFs).setVerifyChecksum(eq(false));
    reset(mockFs);
    fs.setVerifyChecksum(true);
    verify(mockFs).setVerifyChecksum(eq(true));
  }

  @Test
  public void testWriteChecksumPassthru() {
    FileSystem mockFs = mock(FileSystem.class);
    FileSystem fs = new FilterFileSystem(mockFs);

    fs.setWriteChecksum(false);
    verify(mockFs).setWriteChecksum(eq(false));
    reset(mockFs);
    fs.setWriteChecksum(true);
    verify(mockFs).setWriteChecksum(eq(true));
  }

  private void checkInit(FilterFileSystem fs, boolean expectInit)
      throws Exception {
    URI uri = URI.create("filter:/");
    fs.initialize(uri, conf);
    
    FileSystem embedFs = fs.getRawFileSystem();
    if (expectInit) {
      verify(embedFs, times(1)).initialize(eq(uri), eq(conf));
    } else {
      verify(embedFs, times(0)).initialize(any(URI.class), any(Configuration.class));
    }
  }

  // check the given fs's conf, and all its filtered filesystems
  private void checkFsConf(FileSystem fs, Configuration conf, int expectDepth) {
    int depth = 0;
    while (true) {
      depth++; 
      assertFalse("depth "+depth+">"+expectDepth, depth > expectDepth);
      assertEquals(conf, fs.getConf());
      if (!(fs instanceof FilterFileSystem)) {
        break;
      }
      fs = ((FilterFileSystem) fs).getRawFileSystem();
    }
    assertEquals(expectDepth, depth);
  }
  
  private static class FilterLocalFileSystem extends FilterFileSystem {
    FilterLocalFileSystem() {
      super(new LocalFileSystem());
    }
  }
}
