/*
 * Copyright (c) 2008, 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 4313887 6838333
 * @summary Unit test for java.nio.file.attribute.PosixFileAttributeView
 * @library ../..
 */

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

/**
 * Unit test for PosixFileAttributeView, passing silently if this attribute
 * view is not available.
 */

public class Basic {

    /**
     * Use view to update permission to the given mode and check that the
     * permissions have been updated.
     */
    static void testPermissions(Path file, String mode) throws IOException {
        System.out.format("change mode: %s\n", mode);
        Set<PosixFilePermission> perms = PosixFilePermissions.fromString(mode);

        // change permissions and re-read them.
        Attributes.setPosixFilePermissions(file, perms);
        Set<PosixFilePermission> current = Attributes
            .readPosixFileAttributes(file).permissions();
        if (!current.equals(perms)) {
            throw new RuntimeException("Actual permissions: " +
                PosixFilePermissions.toString(current) + ", expected: " +
                PosixFilePermissions.toString(perms));
        }

        // repeat test using setAttribute/getAttribute
        file.setAttribute("posix:permissions", perms);
        current = (Set<PosixFilePermission>)file.getAttribute("posix:permissions");
        if (!current.equals(perms)) {
            throw new RuntimeException("Actual permissions: " +
                PosixFilePermissions.toString(current) + ", expected: " +
                PosixFilePermissions.toString(perms));
        }
    }

    /**
     * Check that the actual permissions of a file match or make it more
     * secure than requested
     */
    static void checkSecure(Set<PosixFilePermission> requested,
                            Set<PosixFilePermission> actual)
    {
        for (PosixFilePermission perm: actual) {
            if (!requested.contains(perm)) {
                throw new RuntimeException("Actual permissions: " +
                    PosixFilePermissions.toString(actual) + ", requested: " +
                    PosixFilePermissions.toString(requested) +
                    " - file is less secure than requested");
            }
        }
    }

    /**
     * Create file with given mode and check that the file is created with a
     * mode that is not less secure
     */
    static void createWithPermissions(Path file,
                                      String mode)
        throws IOException
    {
        Set<PosixFilePermission> requested = PosixFilePermissions.fromString(mode);
        FileAttribute<Set<PosixFilePermission>> attr =
            PosixFilePermissions.asFileAttribute(requested);
        System.out.format("create file with mode: %s\n", mode);
        file.createFile(attr);
        try {
            checkSecure(requested,  file
                .getFileAttributeView(PosixFileAttributeView.class)
                .readAttributes()
                .permissions());
        } finally {
            file.delete();
        }

        System.out.format("create directory with mode: %s\n", mode);
        file.createDirectory(attr);
        try {
            checkSecure(requested,  file
                .getFileAttributeView(PosixFileAttributeView.class)
                .readAttributes()
                .permissions());
        } finally {
            file.delete();
        }
    }

    /**
     * Test the setPermissions/permissions methods.
     */
    static void permissionTests(Path dir)
        throws IOException
    {
        System.out.println("-- Permission Tests  --");

        // create file and test updating and reading its permissions
        Path file = dir.resolve("foo");
        System.out.format("create %s\n", file);
        file.createFile();
        try {
            // get initial permissions so that we can restore them later
            PosixFileAttributeView view = file
                .getFileAttributeView(PosixFileAttributeView.class);
            Set<PosixFilePermission> save = view.readAttributes()
                .permissions();

            // test various modes
            try {
                testPermissions(file, "---------");
                testPermissions(file, "r--------");
                testPermissions(file, "-w-------");
                testPermissions(file, "--x------");
                testPermissions(file, "rwx------");
                testPermissions(file, "---r-----");
                testPermissions(file, "----w----");
                testPermissions(file, "-----x---");
                testPermissions(file, "---rwx---");
                testPermissions(file, "------r--");
                testPermissions(file, "-------w-");
                testPermissions(file, "--------x");
                testPermissions(file, "------rwx");
                testPermissions(file, "r--r-----");
                testPermissions(file, "r--r--r--");
                testPermissions(file, "rw-rw----");
                testPermissions(file, "rwxrwx---");
                testPermissions(file, "rw-rw-r--");
                testPermissions(file, "r-xr-x---");
                testPermissions(file, "r-xr-xr-x");
                testPermissions(file, "rwxrwxrwx");
            } finally {
                view.setPermissions(save);
            }
        } finally {
            file.delete();
        }

        // create link (to file that doesn't exist) and test reading of
        // permissions
        if (TestUtil.supportsLinks(dir)) {
            Path link = dir.resolve("link");
            System.out.format("create link %s\n", link);
            link.createSymbolicLink(file);
            try {
                PosixFileAttributes attrs = Attributes
                    .readPosixFileAttributes(link, NOFOLLOW_LINKS);
                if (!attrs.isSymbolicLink()) {
                    throw new RuntimeException("not a link");
                }
            } finally {
                link.delete();
            }
        }

        System.out.println("OKAY");
    }

    /**
     * Test creating a file and directory with initial permissios
     */
    static void createTests(Path dir)
        throws IOException
    {
        System.out.println("-- Create Tests  --");

        Path file = dir.resolve("foo");

        createWithPermissions(file, "---------");
        createWithPermissions(file, "r--------");
        createWithPermissions(file, "-w-------");
        createWithPermissions(file, "--x------");
        createWithPermissions(file, "rwx------");
        createWithPermissions(file, "---r-----");
        createWithPermissions(file, "----w----");
        createWithPermissions(file, "-----x---");
        createWithPermissions(file, "---rwx---");
        createWithPermissions(file, "------r--");
        createWithPermissions(file, "-------w-");
        createWithPermissions(file, "--------x");
        createWithPermissions(file, "------rwx");
        createWithPermissions(file, "r--r-----");
        createWithPermissions(file, "r--r--r--");
        createWithPermissions(file, "rw-rw----");
        createWithPermissions(file, "rwxrwx---");
        createWithPermissions(file, "rw-rw-r--");
        createWithPermissions(file, "r-xr-x---");
        createWithPermissions(file, "r-xr-xr-x");
        createWithPermissions(file, "rwxrwxrwx");

        System.out.println("OKAY");
    }

    /**
     * Test setOwner/setGroup methods - this test simply exercises the
     * methods to avoid configuration.
     */
    static void ownerTests(Path dir)
        throws IOException
    {
        System.out.println("-- Owner Tests  --");

        Path file = dir.resolve("gus");
        System.out.format("create %s\n", file);

        file.createFile();
        try {

            // read attributes of directory to get owner/group
            PosixFileAttributeView view = file
                .getFileAttributeView(PosixFileAttributeView.class);
            PosixFileAttributes attrs = view.readAttributes();

            // set to existing owner/group
            view.setOwner(attrs.owner());
            view.setGroup(attrs.group());

            // repeat test using set/getAttribute
            UserPrincipal owner = (UserPrincipal)file.getAttribute("posix:owner");
            file.setAttribute("posix:owner", owner);
            UserPrincipal group = (UserPrincipal)file.getAttribute("posix:group");
            file.setAttribute("posix:group", group);

        } finally {
            file.delete();
        }

        System.out.println("OKAY");
    }

    /**
     * Test the lookupPrincipalByName/lookupPrincipalByGroupName methods
     */
    static void lookupPrincipalTests(Path dir)
        throws IOException
    {
        System.out.println("-- Lookup UserPrincipal Tests --");

        UserPrincipalLookupService lookupService = dir.getFileSystem()
            .getUserPrincipalLookupService();

        // read attributes of directory to get owner/group
        PosixFileAttributes attrs = Attributes.readPosixFileAttributes(dir);

        // lookup owner and check it matches file's owner
        System.out.format("lookup: %s\n", attrs.owner().getName());
        try {
            UserPrincipal owner = lookupService.lookupPrincipalByName(attrs.owner().getName());
            if (owner instanceof GroupPrincipal)
                throw new RuntimeException("owner is a group?");
            if (!owner.equals(attrs.owner()))
                throw new RuntimeException("owner different from file owner");
        } catch (UserPrincipalNotFoundException x) {
            System.out.println("user not found - test skipped");
        }

        // lookup group and check it matches file's group-owner
        System.out.format("lookup group: %s\n", attrs.group().getName());
        try {
            GroupPrincipal group = lookupService.lookupPrincipalByGroupName(attrs.group().getName());
            if (!group.equals(attrs.group()))
                throw new RuntimeException("group different from file group-owner");
        } catch (UserPrincipalNotFoundException x) {
            System.out.println("group not found - test skipped");
        }

        // test that UserPrincipalNotFoundException is thrown
        String invalidPrincipal = "scumbag99";
        try {
            System.out.format("lookup: %s\n", invalidPrincipal);
            lookupService.lookupPrincipalByName(invalidPrincipal);
            throw new RuntimeException("'" + invalidPrincipal + "' is a valid user?");
        } catch (UserPrincipalNotFoundException x) {
        }
        try {
            System.out.format("lookup group: %s\n", invalidPrincipal);
            lookupService.lookupPrincipalByGroupName("idonotexist");
            throw new RuntimeException("'" + invalidPrincipal + "' is a valid group?");
        } catch (UserPrincipalNotFoundException x) {
        }
        System.out.println("OKAY");
    }

    /**
     * Test various exceptions are thrown as expected
     */
    @SuppressWarnings("unchecked")
    static void exceptionsTests(Path dir)
        throws IOException
    {
        System.out.println("-- Exceptions --");

        PosixFileAttributeView view = dir
            .getFileAttributeView(PosixFileAttributeView.class);

        // NullPointerException
        try {
            view.setOwner(null);
            throw new RuntimeException("NullPointerException not thrown");
        } catch (NullPointerException x) {
        }
        try {
            view.setGroup(null);
            throw new RuntimeException("NullPointerException not thrown");
        } catch (NullPointerException x) {
        }

        UserPrincipalLookupService lookupService = dir.getFileSystem()
            .getUserPrincipalLookupService();
        try {
            lookupService.lookupPrincipalByName(null);
            throw new RuntimeException("NullPointerException not thrown");
        } catch (NullPointerException x) {
        }
        try {
            lookupService.lookupPrincipalByGroupName(null);
            throw new RuntimeException("NullPointerException not thrown");
        } catch (NullPointerException x) {
        }
        try {
            view.setPermissions(null);
            throw new RuntimeException("NullPointerException not thrown");
        } catch (NullPointerException x) {
        }
        try {
            Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
            perms.add(null);
            view.setPermissions(perms);
            throw new RuntimeException("NullPointerException not thrown");
        }  catch (NullPointerException x) {
        }

        // ClassCastException
        try {
            Set perms = new HashSet();  // raw type
            perms.add(new Object());
            view.setPermissions(perms);
            throw new RuntimeException("ClassCastException not thrown");
        }  catch (ClassCastException x) {
        }

        System.out.println("OKAY");
    }

    public static void main(String[] args) throws IOException {
        Path dir = TestUtil.createTemporaryDirectory();
        try {
            if (!dir.getFileStore().supportsFileAttributeView("posix")) {
                System.out.println("PosixFileAttributeView not supported");
                return;
            }

            permissionTests(dir);
            createTests(dir);
            ownerTests(dir);
            lookupPrincipalTests(dir);
            exceptionsTests(dir);

        } finally {
            TestUtil.removeAll(dir);
        }
    }
}
