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

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.util.EnumSet;

import static org.apache.hadoop.fs.FileContextTestHelper.*;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CreateFlag;
import org.apache.hadoop.fs.FileContext;
import org.apache.hadoop.fs.FileContextTestHelper;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FsConstants;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.viewfs.ChRootedFs;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class TestChRootedFs {
  FileContext fc; // The ChRoootedFs
  FileContext fcTarget; // 
  Path chrootedTo;

  @Before
  public void setUp() throws Exception {
    // create the test root on local_fs
    fcTarget = FileContext.getLocalFSFileContext();
    chrootedTo = FileContextTestHelper.getAbsoluteTestRootPath(fcTarget);
    // In case previous test was killed before cleanup
    fcTarget.delete(chrootedTo, true);
    
    fcTarget.mkdir(chrootedTo, FileContext.DEFAULT_PERM, true);

    Configuration conf = new Configuration();

    // ChRoot to the root of the testDirectory
    fc = FileContext.getFileContext(
        new ChRootedFs(fcTarget.getDefaultFileSystem(), chrootedTo), conf);
  }

  @After
  public void tearDown() throws Exception {
    fcTarget.delete(chrootedTo, true);
  }

  
  @Test
  public void testBasicPaths() {
    URI uri = fc.getDefaultFileSystem().getUri();
    Assert.assertEquals(chrootedTo.toUri(), uri);
    Assert.assertEquals(fc.makeQualified(
        new Path(System.getProperty("user.home"))),
        fc.getWorkingDirectory());
    Assert.assertEquals(fc.makeQualified(
        new Path(System.getProperty("user.home"))),
        fc.getHomeDirectory());
    /*
     * ChRootedFs as its uri like file:///chrootRoot.
     * This is questionable since path.makequalified(uri, path) ignores
     * the pathPart of a uri. So our notion of chrooted URI is questionable.
     * But if we were to fix Path#makeQualified() then  the next test should
     *  have been:

    Assert.assertEquals(
        new Path(chrootedTo + "/foo/bar").makeQualified(
            FsConstants.LOCAL_FS_URI, null),
        fc.makeQualified(new Path( "/foo/bar")));
    */
    
    Assert.assertEquals(
        new Path("/foo/bar").makeQualified(FsConstants.LOCAL_FS_URI, null),
        fc.makeQualified(new Path("/foo/bar")));
  }
  
  
  /** 
   * Test modify operations (create, mkdir, delete, etc) 
   * 
   * Verify the operation via chrootedfs (ie fc) and *also* via the
   *  target file system (ie fclocal) that has been chrooted.
   */
  @Test
  public void testCreateDelete() throws IOException {
    

    // Create file 
    FileContextTestHelper.createFileNonRecursive(fc, "/foo");
    Assert.assertTrue(isFile(fc, new Path("/foo")));
    Assert.assertTrue(isFile(fcTarget, new Path(chrootedTo, "foo")));
    
    // Create file with recursive dir
    FileContextTestHelper.createFile(fc, "/newDir/foo");
    Assert.assertTrue(isFile(fc, new Path("/newDir/foo")));
    Assert.assertTrue(isFile(fcTarget, new Path(chrootedTo,"newDir/foo")));
    
    // Delete the created file
    Assert.assertTrue(fc.delete(new Path("/newDir/foo"), false));
    Assert.assertFalse(exists(fc, new Path("/newDir/foo")));
    Assert.assertFalse(exists(fcTarget, new Path(chrootedTo,"newDir/foo")));
    
    // Create file with a 2 component dirs recursively
    FileContextTestHelper.createFile(fc, "/newDir/newDir2/foo");
    Assert.assertTrue(isFile(fc, new Path("/newDir/newDir2/foo")));
    Assert.assertTrue(isFile(fcTarget, new Path(chrootedTo,"newDir/newDir2/foo")));
    
    // Delete the created file
    Assert.assertTrue(fc.delete(new Path("/newDir/newDir2/foo"), false));
    Assert.assertFalse(exists(fc, new Path("/newDir/newDir2/foo")));
    Assert.assertFalse(exists(fcTarget, new Path(chrootedTo,"newDir/newDir2/foo")));
  }
  
  
  @Test
  public void testMkdirDelete() throws IOException {
    fc.mkdir(FileContextTestHelper.getTestRootPath(fc, "/dirX"), FileContext.DEFAULT_PERM, false);
    Assert.assertTrue(isDir(fc, new Path("/dirX")));
    Assert.assertTrue(isDir(fcTarget, new Path(chrootedTo,"dirX")));
    
    fc.mkdir(FileContextTestHelper.getTestRootPath(fc, "/dirX/dirY"), FileContext.DEFAULT_PERM, false);
    Assert.assertTrue(isDir(fc, new Path("/dirX/dirY")));
    Assert.assertTrue(isDir(fcTarget, new Path(chrootedTo,"dirX/dirY")));
    

    // Delete the created dir
    Assert.assertTrue(fc.delete(new Path("/dirX/dirY"), false));
    Assert.assertFalse(exists(fc, new Path("/dirX/dirY")));
    Assert.assertFalse(exists(fcTarget, new Path(chrootedTo,"dirX/dirY")));
    
    Assert.assertTrue(fc.delete(new Path("/dirX"), false));
    Assert.assertFalse(exists(fc, new Path("/dirX")));
    Assert.assertFalse(exists(fcTarget, new Path(chrootedTo,"dirX")));
    
  }
  @Test
  public void testRename() throws IOException {
    // Rename a file
    FileContextTestHelper.createFile(fc, "/newDir/foo");
    fc.rename(new Path("/newDir/foo"), new Path("/newDir/fooBar"));
    Assert.assertFalse(exists(fc, new Path("/newDir/foo")));
    Assert.assertFalse(exists(fcTarget, new Path(chrootedTo,"newDir/foo")));
    Assert.assertTrue(isFile(fc, FileContextTestHelper.getTestRootPath(fc,"/newDir/fooBar")));
    Assert.assertTrue(isFile(fcTarget, new Path(chrootedTo,"newDir/fooBar")));
    
    
    // Rename a dir
    fc.mkdir(new Path("/newDir/dirFoo"), FileContext.DEFAULT_PERM, false);
    fc.rename(new Path("/newDir/dirFoo"), new Path("/newDir/dirFooBar"));
    Assert.assertFalse(exists(fc, new Path("/newDir/dirFoo")));
    Assert.assertFalse(exists(fcTarget, new Path(chrootedTo,"newDir/dirFoo")));
    Assert.assertTrue(isDir(fc, FileContextTestHelper.getTestRootPath(fc,"/newDir/dirFooBar")));
    Assert.assertTrue(isDir(fcTarget, new Path(chrootedTo,"newDir/dirFooBar")));
  }
  
  
  /**
   * We would have liked renames across file system to fail but 
   * Unfortunately there is not way to distinguish the two file systems 
   * @throws IOException
   */
  @Test
  public void testRenameAcrossFs() throws IOException {
    fc.mkdir(new Path("/newDir/dirFoo"), FileContext.DEFAULT_PERM, true);
    // the root will get interpreted to the root of the chrooted fs.
    fc.rename(new Path("/newDir/dirFoo"), new Path("file:///dirFooBar"));
    FileContextTestHelper.isDir(fc, new Path("/dirFooBar"));
  }
  
  @Test
  public void testList() throws IOException {
    
    FileStatus fs = fc.getFileStatus(new Path("/"));
    Assert.assertTrue(fs.isDirectory());
    //  should return the full path not the chrooted path
    Assert.assertEquals(fs.getPath(), chrootedTo);
    
    // list on Slash
    
    FileStatus[] dirPaths = fc.util().listStatus(new Path("/"));

    Assert.assertEquals(0, dirPaths.length);
    
    

    FileContextTestHelper.createFileNonRecursive(fc, "/foo");
    FileContextTestHelper.createFileNonRecursive(fc, "/bar");
    fc.mkdir(new Path("/dirX"), FileContext.DEFAULT_PERM, false);
    fc.mkdir(FileContextTestHelper.getTestRootPath(fc, "/dirY"),
        FileContext.DEFAULT_PERM, false);
    fc.mkdir(new Path("/dirX/dirXX"), FileContext.DEFAULT_PERM, false);
    
    dirPaths = fc.util().listStatus(new Path("/"));
    Assert.assertEquals(4, dirPaths.length);
    
    // Note the the file status paths are the full paths on target
    fs = FileContextTestHelper.containsPath(fcTarget, "foo", dirPaths);
      Assert.assertNotNull(fs);
      Assert.assertTrue(fs.isFile());
    fs = FileContextTestHelper.containsPath(fcTarget, "bar", dirPaths);
      Assert.assertNotNull(fs);
      Assert.assertTrue(fs.isFile());
    fs = FileContextTestHelper.containsPath(fcTarget, "dirX", dirPaths);
      Assert.assertNotNull(fs);
      Assert.assertTrue(fs.isDirectory());
    fs = FileContextTestHelper.containsPath(fcTarget, "dirY", dirPaths);
      Assert.assertNotNull(fs);
      Assert.assertTrue(fs.isDirectory());
  }
  
  @Test
  public void testWorkingDirectory() throws Exception {

    // First we cd to our test root
    fc.mkdir(new Path("/testWd"), FileContext.DEFAULT_PERM, false);
    Path workDir = new Path("/testWd");
    Path fqWd = fc.makeQualified(workDir);
    fc.setWorkingDirectory(workDir);
    Assert.assertEquals(fqWd, fc.getWorkingDirectory());

    fc.setWorkingDirectory(new Path("."));
    Assert.assertEquals(fqWd, fc.getWorkingDirectory());

    fc.setWorkingDirectory(new Path(".."));
    Assert.assertEquals(fqWd.getParent(), fc.getWorkingDirectory());
    
    // cd using a relative path

    // Go back to our test root
    workDir = new Path("/testWd");
    fqWd = fc.makeQualified(workDir);
    fc.setWorkingDirectory(workDir);
    Assert.assertEquals(fqWd, fc.getWorkingDirectory());
    
    Path relativeDir = new Path("existingDir1");
    Path absoluteDir = new Path(workDir,"existingDir1");
    fc.mkdir(absoluteDir, FileContext.DEFAULT_PERM, true);
    Path fqAbsoluteDir = fc.makeQualified(absoluteDir);
    fc.setWorkingDirectory(relativeDir);
    Assert.assertEquals(fqAbsoluteDir, fc.getWorkingDirectory());
    // cd using a absolute path
    absoluteDir = new Path("/test/existingDir2");
    fqAbsoluteDir = fc.makeQualified(absoluteDir);
    fc.mkdir(absoluteDir, FileContext.DEFAULT_PERM, true);
    fc.setWorkingDirectory(absoluteDir);
    Assert.assertEquals(fqAbsoluteDir, fc.getWorkingDirectory());
    
    // Now open a file relative to the wd we just set above.
    Path absolutePath = new Path(absoluteDir, "foo");
    fc.create(absolutePath, EnumSet.of(CreateFlag.CREATE)).close();
    fc.open(new Path("foo")).close();
    
    // Now mkdir relative to the dir we cd'ed to
    fc.mkdir(new Path("newDir"), FileContext.DEFAULT_PERM, true);
    Assert.assertTrue(isDir(fc, new Path(absoluteDir, "newDir")));

    absoluteDir = getTestRootPath(fc, "nonexistingPath");
    try {
      fc.setWorkingDirectory(absoluteDir);
      Assert.fail("cd to non existing dir should have failed");
    } catch (Exception e) {
      // Exception as expected
    }
    
    // Try a URI
    final String LOCAL_FS_ROOT_URI = "file:///tmp/test";
    absoluteDir = new Path(LOCAL_FS_ROOT_URI + "/existingDir");
    fc.mkdir(absoluteDir, FileContext.DEFAULT_PERM, true);
    fc.setWorkingDirectory(absoluteDir);
    Assert.assertEquals(absoluteDir, fc.getWorkingDirectory());

  }
  
  /*
   * Test resolvePath(p) 
   */
  
  @Test
  public void testResolvePath() throws IOException {
    Assert.assertEquals(chrootedTo, fc.getDefaultFileSystem().resolvePath(new Path("/"))); 
    FileContextTestHelper.createFile(fc, "/foo");
    Assert.assertEquals(new Path(chrootedTo, "foo"),
        fc.getDefaultFileSystem().resolvePath(new Path("/foo"))); 
  }

  @Test(expected=FileNotFoundException.class) 
  public void testResolvePathNonExisting() throws IOException {
      fc.getDefaultFileSystem().resolvePath(new Path("/nonExisting"));
  }
 
}
