/*
 * Copyright (c) 2009, 2012, 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.
 */

/* @test
 * @bug 6595866
 * @summary Test java.io.File operations with sym links
 * @build SymLinks Util
 * @run main SymLinks
 */

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import static java.nio.file.LinkOption.*;

public class SymLinks {
    final static PrintStream out = System.out;

    final static File top = new File(System.getProperty("test.dir", "."));

    // files used by the test

    final static File file              = new File(top, "foofile");
    final static File link2file         = new File(top, "link2file");
    final static File link2link2file    = new File(top, "link2link2file");

    final static File dir               = new File(top, "foodir");
    final static File link2dir          = new File(top, "link2dir");
    final static File link2link2dir     = new File(top, "link2link2dir");

    final static File link2nobody       = new File(top, "link2nobody");
    final static File link2link2nobody  = new File(top, "link2link2nobody");

    /**
     * Setup files, directories, and sym links used by test.
     */
    static void setup() throws IOException {
        // link2link2file -> link2file -> foofile
        FileOutputStream fos = new FileOutputStream(file);
        try {
            fos.write(new byte[16*1024]);
        } finally {
            fos.close();
        }
        mklink(link2file, file);
        mklink(link2link2file, link2file);

        // link2link2dir -> link2dir -> dir
        assertTrue(dir.mkdir());
        mklink(link2dir, dir);
        mklink(link2link2dir, link2dir);

        // link2link2nobody -> link2nobody -> <does-not-exist>
        mklink(link2nobody, new File(top, "DoesNotExist"));
        mklink(link2link2nobody, link2nobody);
    }

    /**
     * Remove files, directories, and sym links used by test.
     */
    static void cleanup() throws IOException {
        if (file != null)
            file.delete();
        if (link2file != null)
            Files.deleteIfExists(link2file.toPath());
        if (link2link2file != null)
            Files.deleteIfExists(link2link2file.toPath());
        if (dir != null)
            dir.delete();
        if (link2dir != null)
            Files.deleteIfExists(link2dir.toPath());
        if (link2link2dir != null)
            Files.deleteIfExists(link2link2dir.toPath());
        if (link2nobody != null)
            Files.deleteIfExists(link2nobody.toPath());
        if (link2link2nobody != null)
            Files.deleteIfExists(link2link2nobody.toPath());
    }

    /**
     * Creates a sym link source->target
     */
    static void mklink(File source, File target) throws IOException {
        Files.createSymbolicLink(source.toPath(), target.toPath());
    }

    /**
     * Returns true if the "link" exists and is a sym link.
     */
    static boolean isSymLink(File link) {
         return Files.isSymbolicLink(link.toPath());
    }

    /**
     * Returns the last modified time of a sym link.
     */
    static long lastModifiedOfSymLink(File link) throws IOException {
        BasicFileAttributes attrs =
            Files.readAttributes(link.toPath(), BasicFileAttributes.class, NOFOLLOW_LINKS);
        assertTrue(attrs.isSymbolicLink());
        return attrs.lastModifiedTime().toMillis();
    }

    /**
     * Returns true if sym links are supported on the file system where
     * "dir" exists.
     */
    static boolean supportsSymLinks(File dir) {
        Path link = dir.toPath().resolve("link");
        Path target = dir.toPath().resolve("target");
        try {
            Files.createSymbolicLink(link, target);
            Files.delete(link);
            return true;
        } catch (UnsupportedOperationException x) {
            return false;
        } catch (IOException x) {
            return false;
        }
    }

    static void assertTrue(boolean v) {
        if (!v) throw new RuntimeException("Test failed");
    }

    static void assertFalse(boolean v) {
        assertTrue(!v);
    }

    static void header(String h) {
        out.println();
        out.println();
        out.println("-- " + h + " --");
    }

    /**
     * Tests go here.
     */
    static void go() throws IOException {

        // check setup
        assertTrue(file.isFile());
        assertTrue(isSymLink(link2file));
        assertTrue(isSymLink(link2link2file));
        assertTrue(dir.isDirectory());
        assertTrue(isSymLink(link2dir));
        assertTrue(isSymLink(link2link2dir));
        assertTrue(isSymLink(link2nobody));
        assertTrue(isSymLink(link2link2nobody));

        header("createNewFile");

        assertFalse(file.createNewFile());
        assertFalse(link2file.createNewFile());
        assertFalse(link2link2file.createNewFile());
        assertFalse(dir.createNewFile());
        assertFalse(link2dir.createNewFile());
        assertFalse(link2link2dir.createNewFile());
        assertFalse(link2nobody.createNewFile());
        assertFalse(link2link2nobody.createNewFile());

        header("mkdir");

        assertFalse(file.mkdir());
        assertFalse(link2file.mkdir());
        assertFalse(link2link2file.mkdir());
        assertFalse(dir.mkdir());
        assertFalse(link2dir.mkdir());
        assertFalse(link2link2dir.mkdir());
        assertFalse(link2nobody.mkdir());
        assertFalse(link2link2nobody.mkdir());

        header("delete");

        File link = new File(top, "mylink");
        try {
            mklink(link, file);
            assertTrue(link.delete());
            assertTrue(!isSymLink(link));
            assertTrue(file.exists());

            mklink(link, link2file);
            assertTrue(link.delete());
            assertTrue(!isSymLink(link));
            assertTrue(link2file.exists());

            mklink(link, dir);
            assertTrue(link.delete());
            assertTrue(!isSymLink(link));
            assertTrue(dir.exists());

            mklink(link, link2dir);
            assertTrue(link.delete());
            assertTrue(!isSymLink(link));
            assertTrue(link2dir.exists());

            mklink(link, link2nobody);
            assertTrue(link.delete());
            assertTrue(!isSymLink(link));
            assertTrue(isSymLink(link2nobody));

        } finally {
            Files.deleteIfExists(link.toPath());
        }

        header("renameTo");

        File newlink = new File(top, "newlink");
        assertTrue(link2file.renameTo(newlink));
        try {
            assertTrue(file.exists());
            assertTrue(isSymLink(newlink));
            assertTrue(!isSymLink(link2file));
        } finally {
            newlink.renameTo(link2file);  // restore link
        }

        assertTrue(link2dir.renameTo(newlink));
        try {
            assertTrue(dir.exists());
            assertTrue(isSymLink(newlink));
            assertTrue(!isSymLink(link2dir));
        } finally {
            newlink.renameTo(link2dir);  // restore link
        }

        header("list");

        final String name = "entry";
        File entry = new File(dir, name);
        try {
            assertTrue(dir.list().length == 0);   // directory should be empty
            assertTrue(link2dir.list().length == 0);
            assertTrue(link2link2dir.list().length == 0);

            assertTrue(entry.createNewFile());
            assertTrue(dir.list().length == 1);
            assertTrue(dir.list()[0].equals(name));

            // access directory by following links
            assertTrue(link2dir.list().length == 1);
            assertTrue(link2dir.list()[0].equals(name));
            assertTrue(link2link2dir.list().length == 1);
            assertTrue(link2link2dir.list()[0].equals(name));

            // files that are not directories
            assertTrue(link2file.list() == null);
            assertTrue(link2nobody.list() == null);

        } finally {
            entry.delete();
        }

        header("isXXX");

        assertTrue(file.isFile());
        assertTrue(link2file.isFile());
        assertTrue(link2link2file.isFile());

        assertTrue(dir.isDirectory());
        assertTrue(link2dir.isDirectory());
        assertTrue(link2link2dir.isDirectory());

        // on Windows we test with the DOS hidden attribute set
        if (System.getProperty("os.name").startsWith("Windows")) {
            DosFileAttributeView view = Files
                .getFileAttributeView(file.toPath(), DosFileAttributeView.class);
            view.setHidden(true);
            try {
                assertTrue(file.isHidden());
                assertTrue(link2file.isHidden());
                assertTrue(link2link2file.isHidden());
            } finally {
                view.setHidden(false);
            }
            assertFalse(file.isHidden());
            assertFalse(link2file.isHidden());
            assertFalse(link2link2file.isHidden());
        }

        header("length");

        long len = file.length();
        assertTrue(len > 0L);
        // these tests should follow links
        assertTrue(link2file.length() == len);
        assertTrue(link2link2file.length() == len);
        assertTrue(link2nobody.length() == 0L);

        header("lastModified / setLastModified");

        // need time to diff between link and file
        long origLastModified = file.lastModified();
        assertTrue(origLastModified != 0L);
        try { Thread.sleep(2000); } catch (InterruptedException x) { }
        file.setLastModified(System.currentTimeMillis());

        long lastModified = file.lastModified();
        assertTrue(lastModified != origLastModified);
        assertTrue(lastModifiedOfSymLink(link2file) != lastModified);
        assertTrue(lastModifiedOfSymLink(link2link2file) != lastModified);
        assertTrue(link2file.lastModified() == lastModified);
        assertTrue(link2link2file.lastModified() == lastModified);
        assertTrue(link2nobody.lastModified() == 0L);

        origLastModified = dir.lastModified();
        assertTrue(origLastModified != 0L);
        dir.setLastModified(0L);
        assertTrue(dir.lastModified() == 0L);
        assertTrue(link2dir.lastModified() == 0L);
        assertTrue(link2link2dir.lastModified() == 0L);
        dir.setLastModified(origLastModified);

        header("setXXX / canXXX");

        assertTrue(file.canRead());
        assertTrue(file.canWrite());
        assertTrue(link2file.canRead());
        assertTrue(link2file.canWrite());
        assertTrue(link2link2file.canRead());
        assertTrue(link2link2file.canWrite());

        if (!Util.isPrivileged() && file.setReadOnly()) {
            assertFalse(file.canWrite());
            assertFalse(link2file.canWrite());
            assertFalse(link2link2file.canWrite());

            assertTrue(file.setWritable(true));             // make writable
            assertTrue(file.canWrite());
            assertTrue(link2file.canWrite());
            assertTrue(link2link2file.canWrite());

            assertTrue(link2file.setReadOnly());            // make read only
            assertFalse(file.canWrite());
            assertFalse(link2file.canWrite());
            assertFalse(link2link2file.canWrite());

            assertTrue(link2link2file.setWritable(true));   // make writable
            assertTrue(file.canWrite());
            assertTrue(link2file.canWrite());
            assertTrue(link2link2file.canWrite());
        }
    }

    public static void main(String[] args) throws IOException {
        if (supportsSymLinks(top)) {
            try {
                setup();
                go();
            } finally {
                cleanup();
            }
        }
    }

}
