/**
 * 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.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.hadoop.test.GenericTestUtils;
import org.junit.Assert;

import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.Shell;
import org.apache.hadoop.util.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.event.Level;

import static org.apache.hadoop.fs.FileContextTestHelper.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

/**
 * <p>
 * A collection of permission tests for the {@link FileContext}.
 * This test should be used for testing an instance of FileContext
 *  that has been initialized to a specific default FileSystem such a
 *  LocalFileSystem, HDFS,S3, etc.
 * </p>
 * <p>
 * To test a given {@link FileSystem} implementation create a subclass of this
 * test and override {@link #setUp()} to initialize the <code>fc</code> 
 * {@link FileContext} instance variable.
 * 
 * Since this a junit 4 you can also do a single setup before 
 * the start of any tests.
 * E.g.
 *     @BeforeClass   public static void clusterSetupAtBegining()
 *     @AfterClass    public static void ClusterShutdownAtEnd()
 * </p>
 */
public abstract class FileContextPermissionBase {  
  
  {
    try {
      GenericTestUtils.setLogLevel(FileSystem.LOG, Level.DEBUG);
    }
    catch(Exception e) {
      System.out.println("Cannot change log level\n"
          + StringUtils.stringifyException(e));
    }
  }
  
  protected FileContextTestHelper fileContextTestHelper;
  protected FileContext fc;

  protected FileContextTestHelper getFileContextHelper() {
      return new FileContextTestHelper(); 
  }
  
  protected abstract FileContext getFileContext() throws Exception;
  
  @Before
  public void setUp() throws Exception {
    fileContextTestHelper = getFileContextHelper();
    fc = getFileContext();
    fc.mkdir(fileContextTestHelper.getTestRootPath(fc), FileContext.DEFAULT_PERM, true);
  }

  @After
  public void tearDown() throws Exception {
    fc.delete(fileContextTestHelper.getTestRootPath(fc), true);
  }
  
  private void cleanupFile(FileContext fc, Path name) throws IOException {
    Assert.assertTrue(exists(fc, name));
    fc.delete(name, true);
    Assert.assertTrue(!exists(fc, name));
  }

  @Test
  public void testCreatePermission() throws IOException {
    if (Path.WINDOWS) {
      System.out.println("Cannot run test for Windows");
      return;
    }
    String filename = "foo";
    Path f = fileContextTestHelper.getTestRootPath(fc, filename);
    fileContextTestHelper.createFile(fc, filename);
    doFilePermissionCheck(FileContext.FILE_DEFAULT_PERM.applyUMask(fc.getUMask()),
                        fc.getFileStatus(f).getPermission());
  }
  
  
  @Test
  public void testSetPermission() throws IOException {
    if (Path.WINDOWS) {
      System.out.println("Cannot run test for Windows");
      return;
    }

    String filename = "foo";
    Path f = fileContextTestHelper.getTestRootPath(fc, filename);
    createFile(fc, f);

    try {
      // create files and manipulate them.
      FsPermission all = new FsPermission((short)0777);
      FsPermission none = new FsPermission((short)0);

      fc.setPermission(f, none);
      doFilePermissionCheck(none, fc.getFileStatus(f).getPermission());

      fc.setPermission(f, all);
      doFilePermissionCheck(all, fc.getFileStatus(f).getPermission());
    }
    finally {cleanupFile(fc, f);}
  }

  @Test
  public void testSetOwner() throws IOException {
    if (Path.WINDOWS) {
      System.out.println("Cannot run test for Windows");
      return;
    }

    String filename = "bar";
    Path f = fileContextTestHelper.getTestRootPath(fc, filename);
    createFile(fc, f);
    List<String> groups = null;
    try {
      groups = getGroups();
      System.out.println(filename + ": " + fc.getFileStatus(f).getPermission());
    }
    catch(IOException e) {
      System.out.println(StringUtils.stringifyException(e));
      System.out.println("Cannot run test");
      return;
    }
    if (groups == null || groups.size() < 1) {
      System.out.println("Cannot run test: need at least one group.  groups="
                         + groups);
      return;
    }

    // create files and manipulate them.
    try {
      String g0 = groups.get(0);
      fc.setOwner(f, null, g0);
      Assert.assertEquals(g0, fc.getFileStatus(f).getGroup());

      if (groups.size() > 1) {
        String g1 = groups.get(1);
        fc.setOwner(f, null, g1);
        Assert.assertEquals(g1, fc.getFileStatus(f).getGroup());
      } else {
        System.out.println("Not testing changing the group since user " +
                           "belongs to only one group.");
      }
      
      try {
        fc.setOwner(f, null, null);
        fail("Exception expected.");
      } catch (IllegalArgumentException iae) {
        // okay
      }
    } 
    finally {cleanupFile(fc, f);}
  }
  
  @Test
  public void testUgi() throws IOException, InterruptedException {
    
    UserGroupInformation otherUser = UserGroupInformation
        .createRemoteUser("otherUser");
    FileContext newFc = otherUser.doAs(new PrivilegedExceptionAction<FileContext>() {

      @Override
      public FileContext run() throws Exception {
        FileContext newFc = FileContext.getFileContext();
        return newFc;
      }
      
    });
    assertEquals("otherUser",newFc.getUgi().getUserName());
  }

  static List<String> getGroups() throws IOException {
    List<String> a = new ArrayList<String>();
    String s = Shell.execCommand(Shell.getGroupsCommand());
    for(StringTokenizer t = new StringTokenizer(s); t.hasMoreTokens(); ) {
      a.add(t.nextToken());
    }
    return a;
  }
  
  
  void doFilePermissionCheck(FsPermission expectedPerm, FsPermission actualPerm) {
  Assert.assertEquals(expectedPerm.applyUMask(getFileMask()), actualPerm);
  }
  
  
  /*
   * Override the method below if the file system being tested masks our
   * certain bits for file masks.
   */
  static final FsPermission FILE_MASK_ZERO = new FsPermission((short) 0);
  FsPermission getFileMask() {
    return FILE_MASK_ZERO;
  }
}
