/**
 * 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 java.io.IOException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.UUID;
import java.util.regex.Pattern;

import com.google.common.collect.Ordering;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.HdfsConfiguration;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.server.namenode.INodeId;
import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.UserGroupInformation;
import org.junit.*;

public class TestGlobPaths {
  
  private static final UserGroupInformation unprivilegedUser =
    UserGroupInformation.createUserForTesting("myuser",
        new String[] { "mygroup" });

  static class RegexPathFilter implements PathFilter {
    
    private final String regex;
    public RegexPathFilter(String regex) {
      this.regex = regex;
    }

    @Override
    public boolean accept(Path path) {
      return path.toString().matches(regex);
    }

  }
  
  static private MiniDFSCluster dfsCluster;
  static private FileSystem fs;
  static private FileSystem privilegedFs;
  static private FileContext fc;
  static private FileContext privilegedFc;
  static final private int NUM_OF_PATHS = 4;
  static private String USER_DIR;
  private final Path[] path = new Path[NUM_OF_PATHS];
  
  @BeforeClass
  public static void setUp() throws Exception {
    final Configuration conf = new HdfsConfiguration();
    dfsCluster = new MiniDFSCluster.Builder(conf).build();

    privilegedFs = FileSystem.get(conf);
    privilegedFc = FileContext.getFileContext(conf);
    // allow unpriviledged user ability to create paths
    privilegedFs.setPermission(new Path("/"),
                               FsPermission.createImmutable((short)0777));
    UserGroupInformation.setLoginUser(unprivilegedUser);
    fs = FileSystem.get(conf);
    fc = FileContext.getFileContext(conf);
    USER_DIR = fs.getHomeDirectory().toUri().getPath().toString();
  }
  
  @AfterClass
  public static void tearDown() throws Exception {
    if(dfsCluster!=null) {
      dfsCluster.shutdown();
    }
  }

  @Test
  public void testMultiGlob() throws IOException {
    FileStatus[] status;
    /*
     *  /dir1/subdir1
     *  /dir1/subdir1/f1
     *  /dir1/subdir1/f2
     *  /dir1/subdir2/f1
     *  /dir2/subdir1
     *  /dir2/subdir2
     *  /dir2/subdir2/f1
     *  /dir3/f1
     *  /dir3/f1
     *  /dir3/f2(dir)
     *  /dir3/subdir2(file)
     *  /dir3/subdir3
     *  /dir3/subdir3/f1
     *  /dir3/subdir3/f1/f1
     *  /dir3/subdir3/f3
     *  /dir4
     */

    Path d1 = new Path(USER_DIR, "dir1");
    Path d11 = new Path(d1, "subdir1");
    Path d12 = new Path(d1, "subdir2");
    
    Path f111 = new Path(d11, "f1");
    fs.createNewFile(f111);
    Path f112 = new Path(d11, "f2");
    fs.createNewFile(f112);
    Path f121 = new Path(d12, "f1");
    fs.createNewFile(f121);
    
    Path d2 = new Path(USER_DIR, "dir2");
    Path d21 = new Path(d2, "subdir1");
    fs.mkdirs(d21);
    Path d22 = new Path(d2, "subdir2");
    Path f221 = new Path(d22, "f1");
    fs.createNewFile(f221);

    Path d3 = new Path(USER_DIR, "dir3");
    Path f31 = new Path(d3, "f1");
    fs.createNewFile(f31);
    Path d32 = new Path(d3, "f2");
    fs.mkdirs(d32);
    Path f32 = new Path(d3, "subdir2"); // fake as a subdir!
    fs.createNewFile(f32);
    Path d33 = new Path(d3, "subdir3");
    Path f333 = new Path(d33, "f3");
    fs.createNewFile(f333);
    Path d331 = new Path(d33, "f1");
    Path f3311 = new Path(d331, "f1");
    fs.createNewFile(f3311);
    Path d4 = new Path(USER_DIR, "dir4");
    fs.mkdirs(d4);

    /*
     * basic 
     */
    Path root = new Path(USER_DIR);
    status = fs.globStatus(root);
    checkStatus(status, root);
    
    status = fs.globStatus(new Path(USER_DIR, "x"));
    assertNull(status);

    status = fs.globStatus(new Path("x"));
    assertNull(status);

    status = fs.globStatus(new Path(USER_DIR, "x/x"));
    assertNull(status);

    status = fs.globStatus(new Path("x/x"));
    assertNull(status);

    status = fs.globStatus(new Path(USER_DIR, "*"));
    checkStatus(status, d1, d2, d3, d4);

    status = fs.globStatus(new Path("*"));
    checkStatus(status, d1, d2, d3, d4);

    status = fs.globStatus(new Path(USER_DIR, "*/x"));
    checkStatus(status);

    status = fs.globStatus(new Path("*/x"));
    checkStatus(status);

    status = fs.globStatus(new Path(USER_DIR, "x/*"));
    checkStatus(status);

    status = fs.globStatus(new Path("x/*"));
    checkStatus(status);

    // make sure full pattern is scanned instead of bailing early with undef
    status = fs.globStatus(new Path(USER_DIR, "x/x/x/*"));
    checkStatus(status);

    status = fs.globStatus(new Path("x/x/x/*"));
    checkStatus(status);

    status = fs.globStatus(new Path(USER_DIR, "*/*"));
    checkStatus(status, d11, d12, d21, d22, f31, d32, f32, d33);

    status = fs.globStatus(new Path("*/*"));
    checkStatus(status, d11, d12, d21, d22, f31, d32, f32, d33);

    /*
     * one level deep
     */
    status = fs.globStatus(new Path(USER_DIR, "dir*/*"));
    checkStatus(status, d11, d12, d21, d22, f31, d32, f32, d33);

    status = fs.globStatus(new Path("dir*/*"));
    checkStatus(status, d11, d12, d21, d22, f31, d32, f32, d33);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*"));
    checkStatus(status, d11, d12, d21, d22, f32, d33);

    status = fs.globStatus(new Path("dir*/subdir*"));
    checkStatus(status, d11, d12, d21, d22, f32, d33);

    status = fs.globStatus(new Path(USER_DIR, "dir*/f*"));
    checkStatus(status, f31, d32);

    status = fs.globStatus(new Path("dir*/f*"));
    checkStatus(status, f31, d32);

    /*
     * subdir1 globs
     */
    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1"));
    checkStatus(status, d11, d21);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/*"));
    checkStatus(status, f111, f112);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/*/*"));
    checkStatus(status);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/x"));
    checkStatus(status);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/x*"));
    checkStatus(status);

    /*
     * subdir2 globs
     */
    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir2"));
    checkStatus(status, d12, d22, f32);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir2/*"));
    checkStatus(status, f121, f221);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir2/*/*"));
    checkStatus(status);

    /*
     * subdir3 globs
     */
    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir3"));
    checkStatus(status, d33);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir3/*"));
    checkStatus(status, d331, f333); 

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir3/*/*"));
    checkStatus(status, f3311);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir3/*/*/*"));
    checkStatus(status);

    /*
     * file1 single dir globs
     */    
    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f1"));
    checkStatus(status, f111);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f1*"));
    checkStatus(status, f111);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f1/*"));
    checkStatus(status);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f1*/*"));
    checkStatus(status);

    /*
     * file1 multi-dir globs
     */
    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1"));
    checkStatus(status, f111, f121, f221, d331);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*"));
    checkStatus(status, f111, f121, f221, d331);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1/*"));
    checkStatus(status, f3311);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*/*"));
    checkStatus(status, f3311);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*/*"));
    checkStatus(status, f3311);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*/x"));
    checkStatus(status);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*/*/*"));
    checkStatus(status);

    /*
     *  file glob multiple files
     */

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*"));
    checkStatus(status, d11, d12, d21, d22, f32, d33);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/*"));
    checkStatus(status, f111, f112, f121, f221, d331, f333); 

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f*"));
    checkStatus(status, f111, f112, f121, f221, d331, f333);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f*/*"));
    checkStatus(status, f3311);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/*/f1"));
    checkStatus(status, f3311); 

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/*/*"));
    checkStatus(status, f3311); 


    // doesn't exist
    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f3"));
    checkStatus(status);

    status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f3*"));
    checkStatus(status);

    status = fs.globStatus(new Path("{x}"));
    checkStatus(status);

    status = fs.globStatus(new Path("{x,y}"));
    checkStatus(status);

    status = fs.globStatus(new Path("dir*/{x,y}"));
    checkStatus(status);

    status = fs.globStatus(new Path("dir*/{f1,y}"));
    checkStatus(status, f31);

    status = fs.globStatus(new Path("{x,y}"));
    checkStatus(status);
    
    status = fs.globStatus(new Path("/{x/x,y/y}"));
    checkStatus(status);

    status = fs.globStatus(new Path("{x/x,y/y}"));
    checkStatus(status);
    
    status = fs.globStatus(new Path(Path.CUR_DIR));
    checkStatus(status, new Path(USER_DIR));

    status = fs.globStatus(new Path(USER_DIR+"{/dir1}"));
    checkStatus(status, d1);

    status = fs.globStatus(new Path(USER_DIR+"{/dir*}"));
    checkStatus(status, d1, d2, d3, d4);

    status = fs.globStatus(new Path(Path.SEPARATOR), trueFilter);
    checkStatus(status, new Path(Path.SEPARATOR));
    
    status = fs.globStatus(new Path(Path.CUR_DIR), trueFilter);
    checkStatus(status, new Path(USER_DIR));    

    status = fs.globStatus(d1, trueFilter);
    checkStatus(status, d1);

    status = fs.globStatus(new Path(USER_DIR), trueFilter);
    checkStatus(status, new Path(USER_DIR));

    status = fs.globStatus(new Path(USER_DIR, "*"), trueFilter);
    checkStatus(status, d1, d2, d3, d4);

    status = fs.globStatus(new Path("/x/*"), trueFilter);
    checkStatus(status);

    status = fs.globStatus(new Path("/x"), trueFilter);
    assertNull(status);

    status = fs.globStatus(new Path("/x/x"), trueFilter);
    assertNull(status);
    
    /*
     * false filter
     */
    PathFilter falseFilter = new PathFilter() {
      @Override
      public boolean accept(Path path) {
        return false;
      }
    };

    status = fs.globStatus(new Path(Path.SEPARATOR), falseFilter);
    assertNull(status);
    
    status = fs.globStatus(new Path(Path.CUR_DIR), falseFilter);
    assertNull(status);    
    
    status = fs.globStatus(new Path(USER_DIR), falseFilter);
    assertNull(status);
    
    status = fs.globStatus(new Path(USER_DIR, "*"), falseFilter);
    checkStatus(status);

    status = fs.globStatus(new Path("/x/*"), falseFilter);
    checkStatus(status);

    status = fs.globStatus(new Path("/x"), falseFilter);
    assertNull(status);

    status = fs.globStatus(new Path("/x/x"), falseFilter);
    assertNull(status);

    cleanupDFS();
  }
  
  private void checkStatus(FileStatus[] status, Path ... expectedMatches) {
    assertNotNull(status);
    String[] paths = new String[status.length];
    for (int i=0; i < status.length; i++) {
      paths[i] = getPathFromStatus(status[i]);
    }
    String got = StringUtils.join(paths, "\n");
    String expected = StringUtils.join(expectedMatches, "\n");
    assertEquals(expected, got);
  }

  private String getPathFromStatus(FileStatus status) {
    return status.getPath().toUri().getPath();
  }
  
  
  @Test
  public void testPathFilter() throws IOException {
    try {
      String[] files = new String[] { USER_DIR + "/a", USER_DIR + "/a/b" };
      Path[] matchedPath = prepareTesting(USER_DIR + "/*/*", files,
          new RegexPathFilter("^.*" + Pattern.quote(USER_DIR) + "/a/b"));
      assertEquals(1, matchedPath.length);
      assertEquals(path[1], matchedPath[0]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void testPathFilterWithFixedLastComponent() throws IOException {
    try {
      String[] files = new String[] { USER_DIR + "/a", USER_DIR + "/a/b",
                                      USER_DIR + "/c", USER_DIR + "/c/b", };
      Path[] matchedPath = prepareTesting(USER_DIR + "/*/b", files,
          new RegexPathFilter("^.*" + Pattern.quote(USER_DIR) + "/a/b"));
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[1]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestLiteral() throws IOException {
    try {
      String [] files = new String[] {USER_DIR+"/a2c", USER_DIR+"/abc.d"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/abc.d", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[1]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestEscape() throws IOException {
    // Skip the test case on Windows because backslash will be treated as a
    // path separator instead of an escaping character on Windows.
    org.junit.Assume.assumeTrue(!Path.WINDOWS);
    try {
      String [] files = new String[] {USER_DIR+"/ab\\[c.d"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/ab\\[c.d", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[0]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestAny() throws IOException {
    try {
      String [] files = new String[] { USER_DIR+"/abc", USER_DIR+"/a2c",
                                       USER_DIR+"/a.c", USER_DIR+"/abcd"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/a?c", files);
      assertEquals(matchedPath.length, 3);
      assertEquals(matchedPath[0], path[2]);
      assertEquals(matchedPath[1], path[1]);
      assertEquals(matchedPath[2], path[0]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestClosure1() throws IOException {
    try {
      String [] files = new String[] {USER_DIR+"/a", USER_DIR+"/abc",
                                      USER_DIR+"/abc.p", USER_DIR+"/bacd"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/a*", files);
      assertEquals(matchedPath.length, 3);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[1]);
      assertEquals(matchedPath[2], path[2]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestClosure2() throws IOException {
    try {
      String [] files = new String[] {USER_DIR+"/a.", USER_DIR+"/a.txt",
                                     USER_DIR+"/a.old.java", USER_DIR+"/.java"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/a.*", files);
      assertEquals(matchedPath.length, 3);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[2]);
      assertEquals(matchedPath[2], path[1]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestClosure3() throws IOException {
    try {    
      String [] files = new String[] {USER_DIR+"/a.txt.x", USER_DIR+"/ax",
                                      USER_DIR+"/ab37x", USER_DIR+"/bacd"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/a*x", files);
      assertEquals(matchedPath.length, 3);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[2]);
      assertEquals(matchedPath[2], path[1]);
    } finally {
      cleanupDFS();
    } 
  }

  @Test
  public void pTestClosure4() throws IOException {
    try {
      String [] files = new String[] {USER_DIR+"/dir1/file1", 
                                      USER_DIR+"/dir2/file2", 
                                       USER_DIR+"/dir3/file1"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/*/file1", files);
      assertEquals(matchedPath.length, 2);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[2]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestClosure5() throws IOException {
    try {
      String [] files = new String[] {USER_DIR+"/dir1/file1", 
                                      USER_DIR+"/file1"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/*/file1", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[0]);
    } finally {
      cleanupDFS();
    }
  }

  @Test
  public void pTestSet() throws IOException {
    try {    
      String [] files = new String[] {USER_DIR+"/a.c", USER_DIR+"/a.cpp",
                                      USER_DIR+"/a.hlp", USER_DIR+"/a.hxy"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/a.[ch]??", files);
      assertEquals(matchedPath.length, 3);
      assertEquals(matchedPath[0], path[1]);
      assertEquals(matchedPath[1], path[2]);
      assertEquals(matchedPath[2], path[3]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestRange() throws IOException {
    try {    
      String [] files = new String[] {USER_DIR+"/a.d", USER_DIR+"/a.e",
                                      USER_DIR+"/a.f", USER_DIR+"/a.h"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/a.[d-fm]", files);
      assertEquals(matchedPath.length, 3);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[1]);
      assertEquals(matchedPath[2], path[2]);
    } finally {
      cleanupDFS();
    }
  }
  
  @Test
  public void pTestSetExcl() throws IOException {
    try {    
      String [] files = new String[] {USER_DIR+"/a.d", USER_DIR+"/a.e",
                                      USER_DIR+"/a.0", USER_DIR+"/a.h"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/a.[^a-cg-z0-9]", files);
      assertEquals(matchedPath.length, 2);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[1]);
    } finally {
      cleanupDFS();
    }
  }

  @Test
  public void pTestCombination() throws IOException {
    try {    
      String [] files = new String[] {"/user/aa/a.c", "/user/bb/a.cpp",
                                      "/user1/cc/b.hlp", "/user/dd/a.hxy"};
      Path[] matchedPath = prepareTesting("/use?/*/a.[ch]{lp,xy}", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[3]);
    } finally {
      cleanupDFS();
    }
  }

  /* Test {xx,yy} */
  @Test
  public void pTestCurlyBracket() throws IOException {
    Path[] matchedPath;
    String [] files;
    try {
      files = new String[] { USER_DIR+"/a.abcxx", USER_DIR+"/a.abxy",
                             USER_DIR+"/a.hlp", USER_DIR+"/a.jhyy"};
      matchedPath = prepareTesting(USER_DIR+"/a.{abc,jh}??", files);
      assertEquals(matchedPath.length, 2);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[3]);
    } finally {
      cleanupDFS();
    }
    // nested curlies
    try {
      files = new String[] { USER_DIR+"/a.abcxx", USER_DIR+"/a.abdxy",
                             USER_DIR+"/a.hlp", USER_DIR+"/a.jhyy" };
      matchedPath = prepareTesting(USER_DIR+"/a.{ab{c,d},jh}??", files);
      assertEquals(matchedPath.length, 3);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[1]);
      assertEquals(matchedPath[2], path[3]);
    } finally {
      cleanupDFS();
    }
    // cross-component curlies
    try {
      files = new String[] { USER_DIR+"/a/b", USER_DIR+"/a/d",
                             USER_DIR+"/c/b", USER_DIR+"/c/d" };
      matchedPath = prepareTesting(USER_DIR+"/{a/b,c/d}", files);
      assertEquals(matchedPath.length, 2);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[3]);
    } finally {
      cleanupDFS();
    }
    // cross-component absolute curlies
    try {
      files = new String[] { "/a/b", "/a/d",
                             "/c/b", "/c/d" };
      matchedPath = prepareTesting("{/a/b,/c/d}", files);
      assertEquals(matchedPath.length, 2);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[3]);
    } finally {
      cleanupDFS();
    }
    try {
      // test standalone }
      files = new String[] {USER_DIR+"/}bc", USER_DIR+"/}c"};
      matchedPath = prepareTesting(USER_DIR+"/}{a,b}c", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[0]);
      // test {b}
      matchedPath = prepareTesting(USER_DIR+"/}{b}c", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[0]);
      // test {}
      matchedPath = prepareTesting(USER_DIR+"/}{}bc", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[0]);

      // test {,}
      matchedPath = prepareTesting(USER_DIR+"/}{,}bc", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[0]);

      // test {b,}
      matchedPath = prepareTesting(USER_DIR+"/}{b,}c", files);
      assertEquals(matchedPath.length, 2);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[1]);

      // test {,b}
      matchedPath = prepareTesting(USER_DIR+"/}{,b}c", files);
      assertEquals(matchedPath.length, 2);
      assertEquals(matchedPath[0], path[0]);
      assertEquals(matchedPath[1], path[1]);

      // test a combination of {} and ?
      matchedPath = prepareTesting(USER_DIR+"/}{ac,?}", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[1]);
      
      // test ill-formed curly
      boolean hasException = false;
      try {
        prepareTesting(USER_DIR+"}{bc", files);
      } catch (IOException e) {
        assertTrue(e.getMessage().startsWith("Illegal file pattern:") );
        hasException = true;
      }
      assertTrue(hasException);
    } finally {
      cleanupDFS();
    }
  }
  
  /* test that a path name can contain Java regex special characters */
  @Test
  public void pTestJavaRegexSpecialChars() throws IOException {
    try {
      String[] files = new String[] {USER_DIR+"/($.|+)bc", USER_DIR+"/abc"};
      Path[] matchedPath = prepareTesting(USER_DIR+"/($.|+)*", files);
      assertEquals(matchedPath.length, 1);
      assertEquals(matchedPath[0], path[0]);
    } finally {
      cleanupDFS();
    }

  }
  
  private Path[] prepareTesting(String pattern, String[] files)
    throws IOException {
    for(int i=0; i<Math.min(NUM_OF_PATHS, files.length); i++) {
      path[i] = fs.makeQualified(new Path(files[i]));
      if (!fs.mkdirs(path[i])) {
        throw new IOException("Mkdirs failed to create " + path[i].toString());
      }
    }
    Path patternPath = new Path(pattern);
    Path[] globResults = FileUtil.stat2Paths(fs.globStatus(patternPath),
                                             patternPath);
    for(int i=0; i<globResults.length; i++) {
      globResults[i] = 
        globResults[i].makeQualified(fs.getUri(), fs.getWorkingDirectory());
    }
    return globResults;
  }
  
  private Path[] prepareTesting(String pattern, String[] files,
      PathFilter filter) throws IOException {
    for(int i=0; i<Math.min(NUM_OF_PATHS, files.length); i++) {
      path[i] = fs.makeQualified(new Path(files[i]));
      if (!fs.mkdirs(path[i])) {
        throw new IOException("Mkdirs failed to create " + path[i].toString());
      }
    }
    Path patternPath = new Path(pattern);
    Path[] globResults = FileUtil.stat2Paths(fs.globStatus(patternPath, filter),
                                             patternPath);
    for(int i=0; i<globResults.length; i++) {
      globResults[i] = 
        globResults[i].makeQualified(fs.getUri(), fs.getWorkingDirectory());
    }
    return globResults;
  }
  
  private void cleanupDFS() throws IOException {
    fs.delete(new Path(USER_DIR), true);
  }
  
  /**
   * A glob test that can be run on either FileContext or FileSystem.
   */
  private abstract class FSTestWrapperGlobTest {
    FSTestWrapperGlobTest(boolean useFc) {
      if (useFc) {
        this.privWrap = new FileContextTestWrapper(privilegedFc);
        this.wrap = new FileContextTestWrapper(fc);
      } else {
        this.privWrap = new FileSystemTestWrapper(privilegedFs);
        this.wrap = new FileSystemTestWrapper(fs);
      }
    }

    abstract void run() throws Exception;

    final FSTestWrapper privWrap;
    final FSTestWrapper wrap;
  }

  /**
   * Run a glob test on FileSystem.
   */
  private void testOnFileSystem(FSTestWrapperGlobTest test) throws Exception {
    try {
      fc.mkdir(new Path(USER_DIR), FsPermission.getDefault(), true);
      test.run();
    } finally {
      fc.delete(new Path(USER_DIR), true);
    }
  }

  /**
   * Run a glob test on FileContext.
   */
  private void testOnFileContext(FSTestWrapperGlobTest test) throws Exception {
    try {
      fs.mkdirs(new Path(USER_DIR));
      test.run();
    } finally {
      cleanupDFS();
    }
  }
  
  /**
   * Accept all paths.
   */
  private static class AcceptAllPathFilter implements PathFilter {
    @Override
    public boolean accept(Path path) {
      return true;
    }
  }

  private static final PathFilter trueFilter = new AcceptAllPathFilter();

  /**
   * Accept only paths ending in Z.
   */
  private static class AcceptPathsEndingInZ implements PathFilter {
    @Override
    public boolean accept(Path path) {
      String stringPath = path.toUri().getPath();
      return stringPath.endsWith("z");
    }
  }

  /**
   * Test globbing through symlinks.
   */
  private class TestGlobWithSymlinks extends FSTestWrapperGlobTest {
    TestGlobWithSymlinks(boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      // Test that globbing through a symlink to a directory yields a path
      // containing that symlink.
      wrap.mkdir(new Path(USER_DIR + "/alpha"), FsPermission.getDirDefault(),
          false);
      wrap.createSymlink(new Path(USER_DIR + "/alpha"), new Path(USER_DIR
          + "/alphaLink"), false);
      wrap.mkdir(new Path(USER_DIR + "/alphaLink/beta"),
          FsPermission.getDirDefault(), false);
      // Test simple glob
      FileStatus[] statuses = wrap.globStatus(new Path(USER_DIR + "/alpha/*"),
          new AcceptAllPathFilter());
      Assert.assertEquals(1, statuses.length);
      Assert.assertEquals(USER_DIR + "/alpha/beta", statuses[0].getPath()
          .toUri().getPath());
      // Test glob through symlink
      statuses = wrap.globStatus(new Path(USER_DIR + "/alphaLink/*"),
          new AcceptAllPathFilter());
      Assert.assertEquals(1, statuses.length);
      Assert.assertEquals(USER_DIR + "/alphaLink/beta", statuses[0].getPath()
          .toUri().getPath());
      // If the terminal path component in a globbed path is a symlink,
      // we don't dereference that link.
      wrap.createSymlink(new Path("beta"), new Path(USER_DIR
          + "/alphaLink/betaLink"), false);
      statuses = wrap.globStatus(new Path(USER_DIR + "/alpha/betaLi*"),
          new AcceptAllPathFilter());
      Assert.assertEquals(1, statuses.length);
      Assert.assertEquals(USER_DIR + "/alpha/betaLink", statuses[0].getPath()
          .toUri().getPath());
      // todo: test symlink-to-symlink-to-dir, etc.
    }
  }

  @Ignore
  @Test
  public void testGlobWithSymlinksOnFS() throws Exception {
    testOnFileSystem(new TestGlobWithSymlinks(false));
  }

  @Ignore
  @Test
  public void testGlobWithSymlinksOnFC() throws Exception {
    testOnFileContext(new TestGlobWithSymlinks(true));
  }

  /**
   * Test globbing symlinks to symlinks.
   *
   * Also test globbing dangling symlinks.  It should NOT throw any exceptions!
   */
  private class TestGlobWithSymlinksToSymlinks extends
      FSTestWrapperGlobTest {
    TestGlobWithSymlinksToSymlinks(boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      // Test that globbing through a symlink to a symlink to a directory
      // fully resolves
      wrap.mkdir(new Path(USER_DIR + "/alpha"), FsPermission.getDirDefault(),
          false);
      wrap.createSymlink(new Path(USER_DIR + "/alpha"), new Path(USER_DIR
          + "/alphaLink"), false);
      wrap.createSymlink(new Path(USER_DIR + "/alphaLink"), new Path(USER_DIR
          + "/alphaLinkLink"), false);
      wrap.mkdir(new Path(USER_DIR + "/alpha/beta"),
          FsPermission.getDirDefault(), false);
      // Test glob through symlink to a symlink to a directory
      FileStatus statuses[] = wrap.globStatus(new Path(USER_DIR
          + "/alphaLinkLink"), new AcceptAllPathFilter());
      Assert.assertEquals(1, statuses.length);
      Assert.assertEquals(USER_DIR + "/alphaLinkLink", statuses[0].getPath()
          .toUri().getPath());
      statuses = wrap.globStatus(new Path(USER_DIR + "/alphaLinkLink/*"),
          new AcceptAllPathFilter());
      Assert.assertEquals(1, statuses.length);
      Assert.assertEquals(USER_DIR + "/alphaLinkLink/beta", statuses[0]
          .getPath().toUri().getPath());
      // Test glob of dangling symlink (theta does not actually exist)
      wrap.createSymlink(new Path(USER_DIR + "theta"), new Path(USER_DIR
          + "/alpha/kappa"), false);
      statuses = wrap.globStatus(new Path(USER_DIR + "/alpha/kappa/kappa"),
          new AcceptAllPathFilter());
      Assert.assertNull(statuses);
      // Test glob of symlinks
      wrap.createFile(USER_DIR + "/alpha/beta/gamma");
      wrap.createSymlink(new Path(USER_DIR + "gamma"), new Path(USER_DIR
          + "/alpha/beta/gammaLink"), false);
      wrap.createSymlink(new Path(USER_DIR + "gammaLink"), new Path(USER_DIR
          + "/alpha/beta/gammaLinkLink"), false);
      wrap.createSymlink(new Path(USER_DIR + "gammaLinkLink"), new Path(
          USER_DIR + "/alpha/beta/gammaLinkLinkLink"), false);
      statuses = wrap.globStatus(new Path(USER_DIR
          + "/alpha/*/gammaLinkLinkLink"), new AcceptAllPathFilter());
      Assert.assertEquals(1, statuses.length);
      Assert.assertEquals(USER_DIR + "/alpha/beta/gammaLinkLinkLink",
          statuses[0].getPath().toUri().getPath());
      statuses = wrap.globStatus(new Path(USER_DIR + "/alpha/beta/*"),
          new AcceptAllPathFilter());
      Assert.assertEquals(USER_DIR + "/alpha/beta/gamma;" + USER_DIR
          + "/alpha/beta/gammaLink;" + USER_DIR + "/alpha/beta/gammaLinkLink;"
          + USER_DIR + "/alpha/beta/gammaLinkLinkLink",
          TestPath.mergeStatuses(statuses));
      // Let's create two symlinks that point to each other, and glob on them.
      wrap.createSymlink(new Path(USER_DIR + "tweedledee"), new Path(USER_DIR
          + "/tweedledum"), false);
      wrap.createSymlink(new Path(USER_DIR + "tweedledum"), new Path(USER_DIR
          + "/tweedledee"), false);
      statuses = wrap.globStatus(
          new Path(USER_DIR + "/tweedledee/unobtainium"),
          new AcceptAllPathFilter());
      Assert.assertNull(statuses);
    }
  }

  @Ignore
  @Test
  public void testGlobWithSymlinksToSymlinksOnFS() throws Exception {
    testOnFileSystem(new TestGlobWithSymlinksToSymlinks(false));
  }

  @Ignore
  @Test
  public void testGlobWithSymlinksToSymlinksOnFC() throws Exception {
    testOnFileContext(new TestGlobWithSymlinksToSymlinks(true));
  }

  /**
   * Test globbing symlinks with a custom PathFilter
   */
  private class TestGlobSymlinksWithCustomPathFilter extends
      FSTestWrapperGlobTest {
    TestGlobSymlinksWithCustomPathFilter(boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      // Test that globbing through a symlink to a symlink to a directory
      // fully resolves
      wrap.mkdir(new Path(USER_DIR + "/alpha"), FsPermission.getDirDefault(),
          false);
      wrap.createSymlink(new Path(USER_DIR + "/alpha"), new Path(USER_DIR
          + "/alphaLinkz"), false);
      wrap.mkdir(new Path(USER_DIR + "/alpha/beta"),
          FsPermission.getDirDefault(), false);
      wrap.mkdir(new Path(USER_DIR + "/alpha/betaz"),
          FsPermission.getDirDefault(), false);
      // Test glob through symlink to a symlink to a directory, with a
      // PathFilter
      FileStatus statuses[] = wrap.globStatus(
          new Path(USER_DIR + "/alpha/beta"), new AcceptPathsEndingInZ());
      Assert.assertNull(statuses);
      statuses = wrap.globStatus(new Path(USER_DIR + "/alphaLinkz/betaz"),
          new AcceptPathsEndingInZ());
      Assert.assertEquals(1, statuses.length);
      Assert.assertEquals(USER_DIR + "/alphaLinkz/betaz", statuses[0].getPath()
          .toUri().getPath());
      statuses = wrap.globStatus(new Path(USER_DIR + "/*/*"),
          new AcceptPathsEndingInZ());
      Assert.assertEquals(USER_DIR + "/alpha/betaz;" + USER_DIR
          + "/alphaLinkz/betaz", TestPath.mergeStatuses(statuses));
      statuses = wrap.globStatus(new Path(USER_DIR + "/*/*"),
          new AcceptAllPathFilter());
      Assert.assertEquals(USER_DIR + "/alpha/beta;" + USER_DIR
          + "/alpha/betaz;" + USER_DIR + "/alphaLinkz/beta;" + USER_DIR
          + "/alphaLinkz/betaz", TestPath.mergeStatuses(statuses));
    }
  }

  @Ignore
  @Test
  public void testGlobSymlinksWithCustomPathFilterOnFS() throws Exception {
    testOnFileSystem(new TestGlobSymlinksWithCustomPathFilter(false));
  }

  @Ignore
  @Test
  public void testGlobSymlinksWithCustomPathFilterOnFC() throws Exception {
    testOnFileContext(new TestGlobSymlinksWithCustomPathFilter(true));
  }

  /**
   * Test that globStatus fills in the scheme even when it is not provided.
   */
  private class TestGlobFillsInScheme extends FSTestWrapperGlobTest {
    TestGlobFillsInScheme(boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      // Verify that the default scheme is hdfs, when we don't supply one.
      wrap.mkdir(new Path(USER_DIR + "/alpha"), FsPermission.getDirDefault(),
          false);
      wrap.createSymlink(new Path(USER_DIR + "/alpha"), new Path(USER_DIR
          + "/alphaLink"), false);
      FileStatus statuses[] = wrap.globStatus(
          new Path(USER_DIR + "/alphaLink"), new AcceptAllPathFilter());
      Assert.assertEquals(1, statuses.length);
      Path path = statuses[0].getPath();
      Assert.assertEquals(USER_DIR + "/alpha", path.toUri().getPath());
      Assert.assertEquals("hdfs", path.toUri().getScheme());

      // FileContext can list a file:/// URI.
      // Since everyone should have the root directory, we list that.
      statuses = fc.util().globStatus(new Path("file:///"),
          new AcceptAllPathFilter());
      Assert.assertEquals(1, statuses.length);
      Path filePath = statuses[0].getPath();
      Assert.assertEquals("file", filePath.toUri().getScheme());
      Assert.assertEquals("/", filePath.toUri().getPath());

      // The FileSystem should have scheme 'hdfs'
      Assert.assertEquals("hdfs", fs.getScheme());
    }
  }

  @Test
  public void testGlobFillsInSchemeOnFS() throws Exception {
    testOnFileSystem(new TestGlobFillsInScheme(false));
  }

  @Test
  public void testGlobFillsInSchemeOnFC() throws Exception {
    testOnFileContext(new TestGlobFillsInScheme(true));
  }

  /**
   * Test that globStatus works with relative paths.
   **/
  private class TestRelativePath extends FSTestWrapperGlobTest {
    TestRelativePath(boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      String[] files = new String[] { "a", "abc", "abc.p", "bacd" };

      Path[] path = new Path[files.length];
      for(int i=0; i <  files.length; i++) {
        path[i] = wrap.makeQualified(new Path(files[i]));
        wrap.mkdir(path[i], FsPermission.getDirDefault(), true);
      }

      Path patternPath = new Path("a*");
      Path[] globResults = FileUtil.stat2Paths(wrap.globStatus(patternPath,
            new AcceptAllPathFilter()),
          patternPath);

      for(int i=0; i < globResults.length; i++) {
        globResults[i] = wrap.makeQualified(globResults[i]);
      }

      assertEquals(globResults.length, 3);

      // The default working directory for FileSystem is the user's home
      // directory.  For FileContext, the default is based on the UNIX user that
      // started the jvm.  This is arguably a bug (see HADOOP-10944 for
      // details).  We work around it here by explicitly calling
      // getWorkingDirectory and going from there.
      String pwd = wrap.getWorkingDirectory().toUri().getPath();
      assertEquals(pwd + "/a;" + pwd + "/abc;" + pwd + "/abc.p",
                               TestPath.mergeStatuses(globResults));
    }
  }

  @Test
  public void testRelativePathOnFS() throws Exception {
    testOnFileSystem(new TestRelativePath(false));
  }

  @Test
  public void testRelativePathOnFC() throws Exception {
    testOnFileContext(new TestRelativePath(true));
  }
  
  /**
   * Test that trying to glob through a directory we don't have permission
   * to list fails with AccessControlException rather than succeeding or
   * throwing any other exception.
   **/
  private class TestGlobAccessDenied extends FSTestWrapperGlobTest {
    TestGlobAccessDenied(boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      privWrap.mkdir(new Path("/nopermission/val"),
          new FsPermission((short)0777), true);
      privWrap.mkdir(new Path("/norestrictions/val"),
          new FsPermission((short)0777), true);
      privWrap.setPermission(new Path("/nopermission"),
          new FsPermission((short)0));
      try {
        wrap.globStatus(new Path("/no*/*"),
            new AcceptAllPathFilter());
        Assert.fail("expected to get an AccessControlException when " +
            "globbing through a directory we don't have permissions " +
            "to list.");
      } catch (AccessControlException ioe) {
      }

      Assert.assertEquals("/norestrictions/val",
        TestPath.mergeStatuses(wrap.globStatus(
            new Path("/norestrictions/*"),
                new AcceptAllPathFilter())));
    }
  }

  @Test
  public void testGlobAccessDeniedOnFS() throws Exception {
    testOnFileSystem(new TestGlobAccessDenied(false));
  }

  @Test
  public void testGlobAccessDeniedOnFC() throws Exception {
    testOnFileContext(new TestGlobAccessDenied(true));
  }

  /**
   * Test that trying to list a reserved path on HDFS via the globber works.
   **/
  private class TestReservedHdfsPaths extends FSTestWrapperGlobTest {
    TestReservedHdfsPaths(boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      String reservedRoot = "/.reserved/.inodes/" + INodeId.ROOT_INODE_ID;
      Assert.assertEquals(reservedRoot,
        TestPath.mergeStatuses(wrap.
            globStatus(new Path(reservedRoot), new AcceptAllPathFilter())));
    }
  }

  @Test
  public void testReservedHdfsPathsOnFS() throws Exception {
    testOnFileSystem(new TestReservedHdfsPaths(false));
  }

  @Test
  public void testReservedHdfsPathsOnFC() throws Exception {
    testOnFileContext(new TestReservedHdfsPaths(true));
  }
  
  /**
   * Test trying to glob the root.  Regression test for HDFS-5888.
   **/
  private class TestGlobRoot extends FSTestWrapperGlobTest {
    TestGlobRoot (boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      final Path rootPath = new Path("/");
      FileStatus oldRootStatus = wrap.getFileStatus(rootPath);
      String newOwner = UUID.randomUUID().toString();
      privWrap.setOwner(new Path("/"), newOwner, null);
      FileStatus[] status = 
          wrap.globStatus(rootPath, new AcceptAllPathFilter());
      Assert.assertEquals(1, status.length);
      Assert.assertEquals(newOwner, status[0].getOwner());
      privWrap.setOwner(new Path("/"), oldRootStatus.getOwner(), null);
    }
  }

  @Test
  public void testGlobRootOnFS() throws Exception {
    testOnFileSystem(new TestGlobRoot(false));
  }

  @Test
  public void testGlobRootOnFC() throws Exception {
    testOnFileContext(new TestGlobRoot(true));
  }

  /**
   * Test glob expressions that don't appear at the end of the path.  Regression
   * test for HADOOP-10957.
   **/
  private class TestNonTerminalGlobs extends FSTestWrapperGlobTest {
    TestNonTerminalGlobs(boolean useFc) {
      super(useFc);
    }

    void run() throws Exception {
      try {
        privWrap.mkdir(new Path("/filed_away/alpha"),
            new FsPermission((short)0777), true);
        privWrap.createFile(new Path("/filed"), 0);
        FileStatus[] statuses =
            wrap.globStatus(new Path("/filed*/alpha"),
                  new AcceptAllPathFilter());
        Assert.assertEquals(1, statuses.length);
        Assert.assertEquals("/filed_away/alpha", statuses[0].getPath()
            .toUri().getPath());
        privWrap.mkdir(new Path("/filed_away/alphabet"),
            new FsPermission((short)0777), true);
        privWrap.mkdir(new Path("/filed_away/alphabet/abc"),
            new FsPermission((short)0777), true);
        statuses = wrap.globStatus(new Path("/filed*/alph*/*b*"),
                  new AcceptAllPathFilter());
        Assert.assertEquals(1, statuses.length);
        Assert.assertEquals("/filed_away/alphabet/abc", statuses[0].getPath()
            .toUri().getPath());
      } finally {
        privWrap.delete(new Path("/filed"), true);
        privWrap.delete(new Path("/filed_away"), true);
      }
    }
  }

  @Test
  public void testNonTerminalGlobsOnFS() throws Exception {
    testOnFileSystem(new TestNonTerminalGlobs(false));
  }

  @Test
  public void testNonTerminalGlobsOnFC() throws Exception {
    testOnFileContext(new TestNonTerminalGlobs(true));
  }

  @Test
  public void testLocalFilesystem() throws Exception {
    Configuration conf = new Configuration();
    FileSystem fs = FileSystem.getLocal(conf);
    String localTmp = System.getProperty("java.io.tmpdir");
    Path base = new Path(new Path(localTmp), UUID.randomUUID().toString());
    Assert.assertTrue(fs.mkdirs(base));
    Assert.assertTrue(fs.mkdirs(new Path(base, "e")));
    Assert.assertTrue(fs.mkdirs(new Path(base, "c")));
    Assert.assertTrue(fs.mkdirs(new Path(base, "a")));
    Assert.assertTrue(fs.mkdirs(new Path(base, "d")));
    Assert.assertTrue(fs.mkdirs(new Path(base, "b")));
    fs.deleteOnExit(base);
    FileStatus[] status = fs.globStatus(new Path(base, "*"));
    ArrayList list = new ArrayList();
    for (FileStatus f: status) {
        list.add(f.getPath().toString());
    }
    boolean sorted = Ordering.natural().isOrdered(list);
    Assert.assertTrue(sorted);
  }
}

