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

import java.io.*;
import java.nio.file.Path;
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)
            link2file.toPath().deleteIfExists();
        if (link2link2file != null)
            link2link2file.toPath().deleteIfExists();
        if (dir != null)
            dir.delete();
        if (link2dir != null)
            link2dir.toPath().deleteIfExists();
        if (link2link2dir != null)
            link2link2dir.toPath().deleteIfExists();
        if (link2nobody != null)
            link2nobody.toPath().deleteIfExists();
        if (link2link2nobody != null)
            link2link2nobody.toPath().deleteIfExists();
    }

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

    /**
     * Returns true if the "link" exists and is a sym link.
     */
    static boolean isSymLink(File link) {
         try {
            BasicFileAttributes attrs =
                Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
            return attrs.isSymbolicLink();
         } catch (IOException x) {
             return false;
         }
    }

    /**
     * Returns the last modified time of a sym link.
     */
    static long lastModifiedOfSymLink(File link) throws IOException {
        BasicFileAttributes attrs =
            Attributes.readBasicFileAttributes(link.toPath(), 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 {
            link.createSymbolicLink(target);
            link.delete();
            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 {
            link.toPath().deleteIfExists();
        }

        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 = file.toPath()
                .getFileAttributeView(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 (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();
            }
        }
    }

}
