/*
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
   @summary Common definitions for general exhaustive pathname tests
   @author  Mark Reinhold
 */

import java.io.*;
import java.util.*;
import java.nio.file.*;


public class General {

    public static boolean debug = false;

    private static boolean win32 = (File.separatorChar == '\\');

    private static int gensymCounter = 0;

    protected static final String userDir = System.getProperty("user.dir");

    protected static String baseDir = null;
    protected static String relative = null;

    /* Generate a filename unique to this run */
    private static String gensym() {
        return "x." + ++gensymCounter;
    }

    /**
     * Create files and folders in the test working directory.
     * The purpose is to make sure the test will not go out of
     * its user dir when walking the file tree.
     *
     * @param  depth    The number of directory levels to be created under
     *                  the user directory. It should be the maximum value
     *                  of the depths passed to checkNames method (including
     *                  direct or indirect calling) in a whole test.
     */
    protected static void initTestData(int depth) throws IOException {
        File parent = new File(userDir);
        for (int i = 0; i < depth; i++) {
            File tmp = new File(parent, gensym());
            tmp.createNewFile();
            tmp = new File(parent, gensym());
            if (tmp.mkdir())
                parent = tmp;
            else
                throw new IOException("Fail to create directory, " + tmp);
        }
        baseDir = parent.getAbsolutePath();
        relative = baseDir.substring(userDir.length() + 1);
    }

    /**
     * Find a file in the given subdirectory, or descend into further
     * subdirectories, if any, if no file is found here.  Return null if no
     * file can be found anywhere beneath the given subdirectory.
     * @param  dir     Directory at which we started
     * @param  subdir  Subdirectory that we're exploring
     * @param  dl      Listing of subdirectory
     */
    private static String findSomeFile(String dir, String subdir, String[] dl) {
        for (int i = 0; i < dl.length; i++) {
            File f = new File(subdir, dl[i]);
            File df = new File(dir, f.getPath());
            if (Files.isRegularFile(df.toPath(), LinkOption.NOFOLLOW_LINKS)) {
                return f.getPath();
            }
        }
        for (int i = 0; i < dl.length; i++) {
            File f = (subdir.length() == 0) ? new File(dl[i])
                                            : new File(subdir, dl[i]);
            File df = new File(dir, f.getPath());
            if (Files.isDirectory(df.toPath(), LinkOption.NOFOLLOW_LINKS)) {
                String[] dl2 = df.list();
                if (dl2 != null) {
                    String ff = findSomeFile(dir, f.getPath(), dl2);
                    if (ff != null) return ff;
                }
            }
        }
        return null;
    }


    /**
     * Construct a string that names a file in the given directory.  If create
     * is true, then create a file if none is found, and throw an exception if
     * that is not possible; otherwise, return null if no file can be found.
     */
    private static String findSomeFile(String dir, boolean create) {
        File d = new File(dir);
        String[] dl = d.list();
        if (dl == null) {
            throw new RuntimeException("Can't list " + dir);
        }
        for (int i = 0; i < dl.length; i++) {
            File f = new File(dir, dl[i]);
            if (Files.isRegularFile(f.toPath(), LinkOption.NOFOLLOW_LINKS)) {
                return dl[i];
            }
        }
        String f = findSomeFile(dir, "", dl);
        if (f != null) {
            return f;
        }
        if (create) {
            File nf = new File(d, gensym());
            OutputStream os;
            try {
                os = new FileOutputStream(nf);
                os.close();
            } catch (IOException x) {
                throw new RuntimeException("Can't create a file in " + dir);
            }
            return nf.getName();
        }
        return null;
    }


    /**
     * Construct a string that names a subdirectory of the given directory.
     * If create is true, then create a subdirectory if none is found, and
     * throw an exception if that is not possible; otherwise, return null if
     * no subdirectory can be found.
     */
    private static String findSomeDir(String dir, boolean create) {
        File d = new File(dir);
        String[] dl = d.list();
        if (dl == null) {
            throw new RuntimeException("Can't list " + dir);
        }
        for (int i = 0; i < dl.length; i++) {
            File f = new File(d, dl[i]);
            if (Files.isDirectory(f.toPath(), LinkOption.NOFOLLOW_LINKS)) {
                String[] dl2 = f.list();
                if (dl2 == null || dl2.length >= 250) {
                    /* Heuristic to avoid scanning huge directories */
                    continue;
                }
                return dl[i];
            }
        }
        if (create) {
            File sd = new File(d, gensym());
            if (sd.mkdir()) return sd.getName();
        }
        return null;
    }


    /** Construct a string that does not name a file in the given directory */
    private static String findNon(String dir) {
        File d = new File(dir);
        String[] x = new String[] { "foo", "bar", "baz" };
        for (int i = 0; i < x.length; i++) {
            File f = new File(d, x[i]);
            if (!f.exists()) {
                return x[i];
            }
        }
        for (int i = 0; i < 1024; i++) {
            String n = "xx" + Integer.toString(i);
            File f = new File(d, n);
            if (!f.exists()) {
                return n;
            }
        }
        throw new RuntimeException("Can't find a non-existent file in " + dir);
    }


    /** Ensure that the named file does not exist */
    public static void ensureNon(String fn) {
        if ((new File(fn)).exists()) {
            throw new RuntimeException("Test path " + fn + " exists");
        }
    }


    /** Tell whether the given character is a "slash" on this platform */
    private static boolean isSlash(char x) {
        if (x == File.separatorChar) return true;
        if (win32 && (x == '/')) return true;
        return false;
    }


    /**
     * Trim trailing slashes from the given string, but leave singleton slashes
     * alone (they denote root directories)
     */
    private static String trimTrailingSlashes(String s) {
        int n = s.length();
        if (n == 0) return s;
        n--;
        while ((n > 0) && isSlash(s.charAt(n))) {
            if ((n >= 1) && s.charAt(n - 1) == ':') break;
            n--;
        }
        return s.substring(0, n + 1);
    }


    /** Concatenate two paths, trimming slashes as needed */
    private static String pathConcat(String a, String b) {
        if (a.length() == 0) return b;
        if (b.length() == 0) return a;
        if (isSlash(a.charAt(a.length() - 1))
            || isSlash(b.charAt(0))
            || (win32 && (a.charAt(a.length() - 1) == ':'))) {
            return a + b;
        } else {
            return a + File.separatorChar + b;
        }
    }



    /** Hash table of input pathnames, used to detect duplicates */
    private static Hashtable<String, String> checked = new Hashtable<>();

    /**
     * Check the given pathname.  Its canonical pathname should be the given
     * answer.  If the path names a file that exists and is readable, then
     * FileInputStream and RandomAccessFile should both be able to open it.
     */
    public static void check(String answer, String path) throws IOException {
        String ans = trimTrailingSlashes(answer);
        if (path.length() == 0) return;
        if (checked.get(path) != null) {
            System.err.println("DUP " + path);
            return;
        }
        checked.put(path, path);

        String cpath;
        try {
            File f = new File(path);
            cpath = f.getCanonicalPath();
            if (f.exists() && f.isFile() && f.canRead()) {
                InputStream in = new FileInputStream(path);
                in.close();
                RandomAccessFile raf = new RandomAccessFile(path, "r");
                raf.close();
            }
        } catch (IOException x) {
            System.err.println(ans + " <-- " + path + " ==> " + x);
            if (debug) return;
            else throw x;
        }
        if (cpath.equals(ans)) {
            System.err.println(ans + " <== " + path);
        } else {
            System.err.println(ans + " <-- " + path + " ==> " + cpath + " MISMATCH");
            if (!debug) {
                throw new RuntimeException("Mismatch: " + path + " ==> " + cpath +
                                           ", should be " + ans);
            }
        }
    }



    /*
     * The following three mutually-recursive methods generate and check a tree
     * of filenames of arbitrary depth.  Each method has (at least) these
     * arguments:
     *
     *     int depth         Remaining tree depth
     *     boolean create    Controls whether test files and directories
     *                       will be created as needed
     *     String ans        Expected answer for the check method (above)
     *     String ask        Input pathname to be passed to the check method
     */


    /** Check a single slash case, plus its children */
    private static void checkSlash(int depth, boolean create,
                                  String ans, String ask, String slash)
        throws Exception
    {
        check(ans, ask + slash);
        checkNames(depth, create,
                   ans.endsWith(File.separator) ? ans : ans + File.separator,
                   ask + slash);
    }


    /** Check slash cases for the given ask string */
    public static void checkSlashes(int depth, boolean create,
                                    String ans, String ask)
        throws Exception
    {
        check(ans, ask);
        if (depth == 0) return;

        checkSlash(depth, create, ans, ask, "/");
        checkSlash(depth, create, ans, ask, "//");
        checkSlash(depth, create, ans, ask, "///");
        if (win32) {
            checkSlash(depth, create, ans, ask, "\\");
            checkSlash(depth, create, ans, ask, "\\\\");
            checkSlash(depth, create, ans, ask, "\\/");
            checkSlash(depth, create, ans, ask, "/\\");
            checkSlash(depth, create, ans, ask, "\\\\\\");
        }
    }


    /** Check name cases for the given ask string */
    public static void checkNames(int depth, boolean create,
                                  String ans, String ask)
        throws Exception
    {
        int d = depth - 1;
        File f = new File(ans);
        String n;

        /* Normal name */
        if (f.exists()) {
            if (Files.isDirectory(f.toPath(), LinkOption.NOFOLLOW_LINKS) && f.list() != null) {
                if ((n = findSomeFile(ans, create)) != null)
                    checkSlashes(d, create, ans + n, ask + n);
                if ((n = findSomeDir(ans, create)) != null)
                    checkSlashes(d, create, ans + n, ask + n);
            }
            n = findNon(ans);
            checkSlashes(d, create, ans + n, ask + n);
        } else {
            n = "foo" + depth;
            checkSlashes(d, create, ans + n, ask + n);
        }

        /* "." */
        checkSlashes(d, create, trimTrailingSlashes(ans), ask + ".");

        /* ".." */
        if ((n = f.getParent()) != null) {
            String n2;
            if (win32
                && ((n2 = f.getParentFile().getParent()) != null)
                && n2.equals("\\\\")) {
                /* Win32 resolves \\foo\bar\.. to \\foo\bar */
                checkSlashes(d, create, ans, ask + "..");
            } else {
                checkSlashes(d, create, n, ask + "..");
            }
        }
        else {
            if (win32)
                checkSlashes(d, create, ans, ask + "..");
            else {
                // Fix for 4237875. We must ensure that we are sufficiently
                // deep in the path hierarchy to test parents this high up
                File thisPath = new File(ask);
                File nextPath = new File(ask + "..");
                if (!thisPath.getCanonicalPath().equals(nextPath.getCanonicalPath()))
                    checkSlashes(d, create, ans + "..", ask + "..");
            }
        }
    }
}
