/**
 * 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.apache.hadoop.fs.FileContextTestHelper.getAbsoluteTestRootDir;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.net.URI;

import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.HdfsConfiguration;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
import org.apache.hadoop.hdfs.server.namenode.NameNode;
import org.apache.hadoop.hdfs.web.WebHdfsFileSystem;
import org.apache.hadoop.hdfs.web.WebHdfsTestUtil;
import org.apache.hadoop.ipc.RemoteException;
import org.apache.log4j.Level;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * Test symbolic links using FileContext and Hdfs.
 */
public class TestFcHdfsSymlink extends FileContextSymlinkBaseTest {

  {
    ((Log4JLogger)NameNode.stateChangeLog).getLogger().setLevel(Level.ALL);
  }

  private static MiniDFSCluster cluster;
  private static WebHdfsFileSystem webhdfs;

  
  protected String getScheme() {
    return "hdfs";
  }

  protected String testBaseDir1() throws IOException {
    return "/test1";
  }
  
  protected String testBaseDir2() throws IOException {
    return "/test2";
  }

  protected URI testURI() {
    return cluster.getURI(0);
  }

  @Override
  protected IOException unwrapException(IOException e) {
    if (e instanceof RemoteException) {
      return ((RemoteException)e).unwrapRemoteException();
    }
    return e;
  }

  @BeforeClass
  public static void testSetUp() throws Exception {
    Configuration conf = new HdfsConfiguration();
    conf.setBoolean(DFSConfigKeys.DFS_WEBHDFS_ENABLED_KEY, true);
    conf.set(FsPermission.UMASK_LABEL, "000");
    cluster = new MiniDFSCluster.Builder(conf).build();
    fc = FileContext.getFileContext(cluster.getURI(0));
    webhdfs = WebHdfsTestUtil.getWebHdfsFileSystem(conf);
  }
  
  @AfterClass
  public static void testTearDown() throws Exception {
    cluster.shutdown();
  }
     
  @Test
  /** Link from Hdfs to LocalFs */
  public void testLinkAcrossFileSystems() throws IOException {
    Path localDir  = new Path("file://"+getAbsoluteTestRootDir(fc)+"/test");
    Path localFile = new Path("file://"+getAbsoluteTestRootDir(fc)+"/test/file");
    Path link      = new Path(testBaseDir1(), "linkToFile");
    FileContext localFc = FileContext.getLocalFSFileContext();
    localFc.delete(localDir, true);
    localFc.mkdir(localDir, FileContext.DEFAULT_PERM, true);
    localFc.setWorkingDirectory(localDir);
    assertEquals(localDir, localFc.getWorkingDirectory());
    createAndWriteFile(localFc, localFile);
    fc.createSymlink(localFile, link, false);
    readFile(link);
    assertEquals(fileSize, fc.getFileStatus(link).getLen());
  }
  
  @Test
  /** Test access a symlink using AbstractFileSystem */
  public void testAccessLinkFromAbstractFileSystem() throws IOException {
    Path file = new Path(testBaseDir1(), "file");
    Path link = new Path(testBaseDir1(), "linkToFile");
    createAndWriteFile(file);
    fc.createSymlink(file, link, false);
    try {
      AbstractFileSystem afs = fc.getDefaultFileSystem();
      afs.open(link);
      fail("Opened a link using AFS");
    } catch (UnresolvedLinkException x) {
      // Expected
    }
  }

  @Test
  /** Test create symlink to / */
  public void testCreateLinkToSlash() throws IOException {
    Path dir  = new Path(testBaseDir1());
    Path file = new Path(testBaseDir1(), "file");
    Path link = new Path(testBaseDir1(), "linkToSlash");
    Path fileViaLink = new Path(testBaseDir1()+"/linkToSlash"+
                                testBaseDir1()+"/file");
    createAndWriteFile(file);
    fc.setWorkingDirectory(dir);
    fc.createSymlink(new Path("/"), link, false);
    readFile(fileViaLink);
    assertEquals(fileSize, fc.getFileStatus(fileViaLink).getLen());
    // Ditto when using another file context since the file system
    // for the slash is resolved according to the link's parent.
    FileContext localFc = FileContext.getLocalFSFileContext();
    Path linkQual = new Path(cluster.getURI(0).toString(), fileViaLink); 
    assertEquals(fileSize, localFc.getFileStatus(linkQual).getLen());    
  }
  
  
  @Test
  /** setPermission affects the target not the link */
  public void testSetPermissionAffectsTarget() throws IOException {    
    Path file       = new Path(testBaseDir1(), "file");
    Path dir        = new Path(testBaseDir2());
    Path linkToFile = new Path(testBaseDir1(), "linkToFile");
    Path linkToDir  = new Path(testBaseDir1(), "linkToDir");
    createAndWriteFile(file);
    fc.createSymlink(file, linkToFile, false);
    fc.createSymlink(dir, linkToDir, false);
    
    // Changing the permissions using the link does not modify
    // the permissions of the link..
    FsPermission perms = fc.getFileLinkStatus(linkToFile).getPermission();
    fc.setPermission(linkToFile, new FsPermission((short)0664));
    fc.setOwner(linkToFile, "user", "group");
    assertEquals(perms, fc.getFileLinkStatus(linkToFile).getPermission());
    // but the file's permissions were adjusted appropriately
    FileStatus stat = fc.getFileStatus(file);
    assertEquals(0664, stat.getPermission().toShort()); 
    assertEquals("user", stat.getOwner());
    assertEquals("group", stat.getGroup());
    // Getting the file's permissions via the link is the same
    // as getting the permissions directly.
    assertEquals(stat.getPermission(), 
                 fc.getFileStatus(linkToFile).getPermission());

    // Ditto for a link to a directory
    perms = fc.getFileLinkStatus(linkToDir).getPermission();
    fc.setPermission(linkToDir, new FsPermission((short)0664));
    fc.setOwner(linkToDir, "user", "group");
    assertEquals(perms, fc.getFileLinkStatus(linkToDir).getPermission());
    stat = fc.getFileStatus(dir);
    assertEquals(0664, stat.getPermission().toShort()); 
    assertEquals("user", stat.getOwner());
    assertEquals("group", stat.getGroup());
    assertEquals(stat.getPermission(), 
                 fc.getFileStatus(linkToDir).getPermission());
  }  

  @Test
  /** Create a symlink using a path with scheme but no authority */
  public void testCreateWithPartQualPathFails() throws IOException {
    Path fileWoAuth = new Path("hdfs:///test/file");
    Path linkWoAuth = new Path("hdfs:///test/link");
    try {
      createAndWriteFile(fileWoAuth);
      fail("HDFS requires URIs with schemes have an authority");
    } catch (RuntimeException e) {
      // Expected
    }
    try {
      fc.createSymlink(new Path("foo"), linkWoAuth, false);
      fail("HDFS requires URIs with schemes have an authority");
    } catch (RuntimeException e) {
      // Expected
    }
  }

  @Test
  /** setReplication affects the target not the link */  
  public void testSetReplication() throws IOException {
    Path file = new Path(testBaseDir1(), "file");
    Path link = new Path(testBaseDir1(), "linkToFile");
    createAndWriteFile(file);
    fc.createSymlink(file, link, false);
    fc.setReplication(link, (short)2);
    assertEquals(0, fc.getFileLinkStatus(link).getReplication());
    assertEquals(2, fc.getFileStatus(link).getReplication());      
    assertEquals(2, fc.getFileStatus(file).getReplication());
  }
  
  @Test
  /** Test create symlink with a max len name */
  public void testCreateLinkMaxPathLink() throws IOException {
    Path dir  = new Path(testBaseDir1());
    Path file = new Path(testBaseDir1(), "file");
    final int maxPathLen = HdfsConstants.MAX_PATH_LENGTH;
    final int dirLen     = dir.toString().length() + 1;
    int   len            = maxPathLen - dirLen;
    
    // Build a MAX_PATH_LENGTH path
    StringBuilder sb = new StringBuilder("");
    for (int i = 0; i < (len / 10); i++) {
      sb.append("0123456789");
    }
    for (int i = 0; i < (len % 10); i++) {
      sb.append("x");
    }
    Path link = new Path(sb.toString());
    assertEquals(maxPathLen, dirLen + link.toString().length()); 
    
    // Check that it works
    createAndWriteFile(file);
    fc.setWorkingDirectory(dir);
    fc.createSymlink(file, link, false);
    readFile(link);
    
    // Now modify the path so it's too large
    link = new Path(sb.toString()+"x");
    try {
      fc.createSymlink(file, link, false);
      fail("Path name should be too long");
    } catch (IOException x) {
      // Expected
    }
  }

  @Test
  /** Test symlink owner */
  public void testLinkOwner() throws IOException {
    Path file = new Path(testBaseDir1(), "file");
    Path link = new Path(testBaseDir1(), "symlinkToFile");
    createAndWriteFile(file);
    fc.createSymlink(file, link, false);
    FileStatus statFile = fc.getFileStatus(file);
    FileStatus statLink = fc.getFileStatus(link);
    assertEquals(statLink.getOwner(), statFile.getOwner());
  }

  @Test
  /** Test WebHdfsFileSystem.craeteSymlink(..). */  
  public void testWebHDFS() throws IOException {
    Path file = new Path(testBaseDir1(), "file");
    Path link = new Path(testBaseDir1(), "linkToFile");
    createAndWriteFile(file);
    webhdfs.createSymlink(file, link, false);
    fc.setReplication(link, (short)2);
    assertEquals(0, fc.getFileLinkStatus(link).getReplication());
    assertEquals(2, fc.getFileStatus(link).getReplication());      
    assertEquals(2, fc.getFileStatus(file).getReplication());
  }
}
