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

/* @test
 * @bug 8017212
 * @summary Examine methods in File.java that access the file system do the
 *          right permission check when a security manager exists.
 * @author Dan Xu
 */

import java.io.File;
import java.io.FilenameFilter;
import java.io.FileFilter;
import java.io.IOException;
import java.security.Permission;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class CheckPermission {

    private static final String CHECK_PERMISSION_TEST = "CheckPermissionTest";

    public enum FileOperation {
        READ, WRITE, DELETE, EXEC
    }

    static class Checks {
        private List<Permission> permissionsChecked = new ArrayList<>();
        private Set<String> propertiesChecked = new HashSet<>();

        private Map<FileOperation, List<String>> fileOperationChecked =
            new EnumMap<>(FileOperation.class);

        List<Permission> permissionsChecked() {
            return permissionsChecked;
        }

        Set<String> propertiesChecked() {
            return propertiesChecked;
        }

        List<String> fileOperationChecked(FileOperation op) {
            return fileOperationChecked.get(op);
        }

        void addFileOperation(FileOperation op, String file) {
            List<String> opList = fileOperationChecked.get(op);
            if (opList == null) {
                opList = new ArrayList<>();
                fileOperationChecked.put(op, opList);
            }
            opList.add(file);
        }
    }

    static ThreadLocal<Checks> myChecks = new ThreadLocal<>();

    static void prepare() {
        myChecks.set(new Checks());
    }

    static class LoggingSecurityManager extends SecurityManager {
        static void install() {
            System.setSecurityManager(new LoggingSecurityManager());
        }

        private void checkFileOperation(FileOperation op, String file) {
            Checks checks = myChecks.get();
            if (checks != null)
                checks.addFileOperation(op, file);
        }

        @Override
        public void checkRead(String file) {
            checkFileOperation(FileOperation.READ, file);
        }

        @Override
        public void checkWrite(String file) {
            checkFileOperation(FileOperation.WRITE, file);
        }

        @Override
        public void checkDelete(String file) {
            checkFileOperation(FileOperation.DELETE, file);
        }

        @Override
        public void checkExec(String file) {
            checkFileOperation(FileOperation.EXEC, file);
        }

        @Override
        public void checkPermission(Permission perm) {
            Checks checks = myChecks.get();
            if (checks != null)
                checks.permissionsChecked().add(perm);
        }

        @Override
        public void checkPropertyAccess(String key) {
            Checks checks = myChecks.get();
            if (checks != null)
                checks.propertiesChecked().add(key);
        }
    }

    static void assertCheckPermission(Class<? extends Permission> type,
            String name)
    {
        for (Permission perm : myChecks.get().permissionsChecked()) {
            if (type.isInstance(perm) && perm.getName().equals(name))
                return;
        }
        throw new RuntimeException(type.getName() + "(\"" + name
            + "\") not checked");
    }

    static void assertCheckPropertyAccess(String key) {
        if (!myChecks.get().propertiesChecked().contains(key))
            throw new RuntimeException("Property " + key + " not checked");
    }

    static void assertChecked(File file, List<String> list) {
        if (list != null && !list.isEmpty()) {
            for (String path : list) {
                if (path.equals(file.getPath()))
                    return;
            }
        }
        throw new RuntimeException("Access not checked");
    }

    static void assertNotChecked(File file, List<String> list) {
        if (list != null && !list.isEmpty()) {
            for (String path : list) {
                if (path.equals(file.getPath()))
                    throw new RuntimeException("Access checked");
            }
        }
    }

    static void assertCheckOperation(File file, Set<FileOperation> ops) {
        for (FileOperation op : ops)
            assertChecked(file, myChecks.get().fileOperationChecked(op));
    }

    static void assertNotCheckOperation(File file, Set<FileOperation> ops) {
        for (FileOperation op : ops)
            assertNotChecked(file, myChecks.get().fileOperationChecked(op));
    }

    static void assertOnlyCheckOperation(File file,
            EnumSet<FileOperation> ops)
    {
        assertCheckOperation(file, ops);
        assertNotCheckOperation(file, EnumSet.complementOf(ops));
    }

    static File testFile, another;

    static void setup() {
        testFile = new File(CHECK_PERMISSION_TEST + System.currentTimeMillis());
        if (testFile.exists()) {
            testFile.delete();
        }

        another = new File(CHECK_PERMISSION_TEST + "Another"
                           + System.currentTimeMillis());
        if (another.exists()) {
            another.delete();
        }

        LoggingSecurityManager.install();
    }

    public static void main(String[] args) throws IOException {
        setup();

        prepare();
        testFile.canRead();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.canWrite();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.exists();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.isDirectory();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.isFile();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.isHidden();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.lastModified();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.length();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.createNewFile();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.list();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return false;
            }
        });
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.listFiles();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return false;
            }
        });
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return false;
            }
        });
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));

        prepare();
        testFile.mkdir();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        if (testFile.exists()) {
            prepare();
            testFile.mkdirs();
            assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
        }

        if (!another.exists()) {
            prepare();
            another.mkdirs();
            assertOnlyCheckOperation(another,
                    EnumSet.of(FileOperation.READ, FileOperation.WRITE));
        }

        prepare();
        another.delete();
        assertOnlyCheckOperation(another, EnumSet.of(FileOperation.DELETE));

        prepare();
        boolean renRst = testFile.renameTo(another);
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
        assertOnlyCheckOperation(another, EnumSet.of(FileOperation.WRITE));

        if (renRst) {
            if (testFile.exists())
                throw new RuntimeException(testFile + " is already renamed to "
                    + another);
            testFile = another;
        }

        prepare();
        testFile.setLastModified(0);
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.setReadOnly();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.setWritable(true, true);
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.setWritable(true);
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.setReadable(true, true);
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.setReadable(true);
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.setExecutable(true, true);
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.setExecutable(true);
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));

        prepare();
        testFile.canExecute();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.EXEC));

        prepare();
        testFile.getTotalSpace();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
        assertCheckPermission(RuntimePermission.class,
                "getFileSystemAttributes");

        prepare();
        testFile.getFreeSpace();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
        assertCheckPermission(RuntimePermission.class,
                "getFileSystemAttributes");

        prepare();
        testFile.getUsableSpace();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
        assertCheckPermission(RuntimePermission.class,
                "getFileSystemAttributes");

        prepare();
        File tmpFile = File.createTempFile(CHECK_PERMISSION_TEST, null);
        assertOnlyCheckOperation(tmpFile, EnumSet.of(FileOperation.WRITE));
        tmpFile.delete();
        assertCheckOperation(tmpFile, EnumSet.of(FileOperation.DELETE));

        prepare();
        tmpFile = File.createTempFile(CHECK_PERMISSION_TEST, null, null);
        assertOnlyCheckOperation(tmpFile, EnumSet.of(FileOperation.WRITE));
        tmpFile.delete();
        assertCheckOperation(tmpFile, EnumSet.of(FileOperation.DELETE));

        prepare();
        testFile.deleteOnExit();
        assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.DELETE));
    }
}
