/*
 * Copyright (c) 2005, 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 4057701 6286712 6364377
 * @ignore until 6492634 and 6501010 is fixed
 * @run build GetXSpace
 * @run shell GetXSpace.sh
 * @summary Basic functionality of File.get-X-Space methods.
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FilePermission;
import java.io.InputStreamReader;
import java.io.IOException;
import java.security.Permission;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.System.out;

public class GetXSpace {

    private static SecurityManager [] sma = { null, new Allow(), new DenyFSA(),
                                              new DenyRead() };

    private static final String name = System.getProperty("os.name");
    private static final String dfFormat;
    static {
        if (name.equals("SunOS") || name.equals("Linux")
                || name.contains("OS X")) {
            // FileSystem Total Used Available Use% MountedOn
            dfFormat = "([^\\s]+)\\s+(\\d+)\\s+\\d+\\s+(\\d+)\\s+\\d+%\\s+([^\\s]+)";
        } else if (name.startsWith("Windows")) {
            // Drive (MountedOn) Available/Total
            dfFormat = "([^\\s]+)\\s+\\(([^\\s]+)\\)\\s+(\\d+)\\/(\\d+)\\s+";
        } else {
            throw new RuntimeException("unrecognized system:"
                                       + " os.name == " + name);
        }
    }
    private static Pattern dfPattern = Pattern.compile(dfFormat);

    private static int fail = 0;
    private static int pass = 0;
    private static Throwable first;

    static void pass() {
        pass++;
    }

    static void fail(String p) {
        if (first == null)
            setFirst(p);
        System.err.format("FAILED: %s%n", p);
        fail++;
    }

    static void fail(String p, long exp, String cmp, long got) {
        String s = String.format("'%s': %d %s %d", p, exp, cmp, got);
        if (first == null)
            setFirst(s);
        System.err.format("FAILED: %s%n", s);
        fail++;
    }

    private static void fail(String p, Class ex) {
        String s = String.format("'%s': expected %s - FAILED%n", p, ex.getName());
        if (first == null)
            setFirst(s);
        System.err.format("FAILED: %s%n", s);
        fail++;
    }

    private static void setFirst(String s) {
        try {
            throw new RuntimeException(s);
        } catch (RuntimeException x) {
            first = x;
        }
    }

    private static class Space {
        private static final long KSIZE = 1024;
        private String name;
        private long total;
        private long free;

        Space(String total, String free, String name) {
            try {
                this.total = Long.valueOf(total) * KSIZE;
                this.free = Long.valueOf(free) * KSIZE;
            } catch (NumberFormatException x) {
                // the regex should have caught this
                assert false;
            }
            this.name = name;
        }

        String name() { return name; }
        long total() { return total; }
        long free() { return free; }
        boolean woomFree(long freeSpace) {
            return ((freeSpace >= (free / 10)) && (freeSpace <= (free * 10)));
        }
        public String toString() {
            return String.format("%s (%d/%d)", name, free, total);
        }
    }

    private static ArrayList space(String f) throws IOException {
        ArrayList al = new ArrayList();

        Process p = null;
        String cmd = "df -k" + (f == null ? "" : " " + f);
        p = Runtime.getRuntime().exec(cmd);
        BufferedReader in = new BufferedReader
            (new InputStreamReader(p.getInputStream()));
        String s;
        int i = 0;
        StringBuilder sb = new StringBuilder();
        while ((s = in.readLine()) != null) {
            // skip header
            if (i++ == 0 && !name.startsWith("Windows")) continue;
            sb.append(s).append("\n");
        }

        Matcher m = dfPattern.matcher(sb);
        int j = 0;
        while (j < sb.length()) {
            if (m.find(j)) {
                if (!name.startsWith("Windows")) {
                    // swap can change while this test is running
                    if (!m.group(1).equals("swap")) {
                        String name = (f == null ? m.group(4): f);
                        al.add(new Space(m.group(2), m.group(3), name));;
                    }
                } else {
                    String name = (f == null ? m.group(2) : f);
                    al.add(new Space(m.group(4), m.group(3), name ));;
                }
                j = m.end() + 1;
            } else {
                throw new RuntimeException("unrecognized df output format: "
                                           + "charAt(" + j + ") = '"
                                           + sb.charAt(j) + "'");
            }
        }

        if (al.size() == 0) {
            // df did not produce output
            String name = (f == null ? "" : f);
            al.add(new Space("0", "0", name));
        }
        in.close();
        return al;
    }

    private static void tryCatch(Space s) {
        out.format("%s:%n", s.name());
        File f = new File(s.name());
        SecurityManager sm = System.getSecurityManager();
        if (sm instanceof Deny) {
            String fmt = "  %14s: \"%s\" thrown as expected%n";
            try {
                f.getTotalSpace();
                fail(s.name(), SecurityException.class);
            } catch (SecurityException x) {
                out.format(fmt, "getTotalSpace", x);
                pass();
            }
            try {
                f.getFreeSpace();
                fail(s.name(), SecurityException.class);
            } catch (SecurityException x) {
                out.format(fmt, "getFreeSpace", x);
                pass();
            }
            try {
                f.getUsableSpace();
                fail(s.name(), SecurityException.class);
            } catch (SecurityException x) {
                out.format(fmt, "getUsableSpace", x);
                pass();
            }
        }
    }

    private static void compare(Space s) {
        File f = new File(s.name());
        long ts = f.getTotalSpace();
        long fs = f.getFreeSpace();
        long us = f.getUsableSpace();

        out.format("%s:%n", s.name());
        String fmt = "  %-4s total= %12d free = %12d usable = %12d%n";
        out.format(fmt, "df", s.total(), 0, s.free());
        out.format(fmt, "getX", ts, fs, us);

        // if the file system can dynamically change size, this check will fail
        if (ts != s.total())
            fail(s.name(), s.total(), "!=", ts);
        else
            pass();

        // unix df returns statvfs.f_bavail
        long tsp = (!name.startsWith("Windows") ? us : fs);
        if (!s.woomFree(tsp))
            fail(s.name(), s.free(), "??", tsp);
        else
            pass();

        if (fs > s.total())
            fail(s.name(), s.total(), ">", fs);
        else
            pass();

        if (us > s.total())
            fail(s.name(), s.total(), ">", us);
        else
            pass();
    }

    private static String FILE_PREFIX = "/getSpace.";
    private static void compareZeroNonExist() {
        File f;
        while (true) {
            f = new File(FILE_PREFIX + Math.random());
            if (f.exists())
                continue;
            break;
        }

        long [] s = { f.getTotalSpace(), f.getFreeSpace(), f.getUsableSpace() };

        for (int i = 0; i < s.length; i++) {
            if (s[i] != 0L)
                fail(f.getName(), s[i], "!=", 0L);
            else
                pass();
        }
    }

    private static void compareZeroExist() {
        try {
            File f = File.createTempFile("tmp", null, new File("."));

            long [] s = { f.getTotalSpace(), f.getFreeSpace(), f.getUsableSpace() };

            for (int i = 0; i < s.length; i++) {
                if (s[i] == 0L)
                    fail(f.getName(), s[i], "==", 0L);
                else
                    pass();
            }
        } catch (IOException x) {
            fail("Couldn't create temp file for test");
        }
    }

    private static class Allow extends SecurityManager {
        public void checkRead(String file) {}
        public void checkPermission(Permission p) {}
        public void checkPermission(Permission p, Object context) {}
    }

    private static class Deny extends SecurityManager {
        public void checkPermission(Permission p) {
            if (p.implies(new RuntimePermission("setSecurityManager"))
                || p.implies(new RuntimePermission("getProtectionDomain")))
              return;
            super.checkPermission(p);
        }

        public void checkPermission(Permission p, Object context) {
            if (p.implies(new RuntimePermission("setSecurityManager"))
                || p.implies(new RuntimePermission("getProtectionDomain")))
              return;
            super.checkPermission(p, context);
        }
    }

    private static class DenyFSA extends Deny {
        private String err = "sorry - getFileSystemAttributes";

        public void checkPermission(Permission p) {
            if (p.implies(new RuntimePermission("getFileSystemAttributes")))
                throw new SecurityException(err);
            super.checkPermission(p);
        }

        public void checkPermission(Permission p, Object context) {
            if (p.implies(new RuntimePermission("getFileSystemAttributes")))
                throw new SecurityException(err);
            super.checkPermission(p, context);
        }
    }

    private static class DenyRead extends Deny {
        private String err = "sorry - checkRead()";

        public void checkRead(String file) {
            throw new SecurityException(err);
        }
    }

    private static void testFile(String dirName) {
        out.format("--- Testing %s%n", dirName);
        ArrayList l;
        try {
            l = space(dirName);
        } catch (IOException x) {
            throw new RuntimeException(dirName + " can't get file system information", x);
        }
        compare((GetXSpace.Space) l.get(0));
    }

    private static void testDF() {
        out.format("--- Testing df");
        // Find all of the partitions on the machine and verify that the size
        // returned by "df" is equivalent to File.getXSpace() values.
        ArrayList l;
        try {
            l = space(null);
        } catch (IOException x) {
            throw new RuntimeException("can't get file system information", x);
        }
        if (l.size() == 0)
            throw new RuntimeException("no partitions?");

        for (int i = 0; i < sma.length; i++) {
            System.setSecurityManager(sma[i]);
            SecurityManager sm = System.getSecurityManager();
            if (sma[i] != null && sm == null)
                throw new RuntimeException("Test configuration error "
                                           + " - can't set security manager");

            out.format("%nSecurityManager = %s%n" ,
                       (sm == null ? "null" : sm.getClass().getName()));
            for (int j = 0; j < l.size(); j++) {
                Space s = (GetXSpace.Space) l.get(j);
                if (sm instanceof Deny) {
                    tryCatch(s);
                } else {
                    compare(s);
                    compareZeroNonExist();
                    compareZeroExist();
                }
            }
        }
    }

    public static void main(String [] args) {
        if (args.length > 0) {
            testFile(args[0]);
        } else {
            testDF();
        }

        if (fail != 0)
            throw new RuntimeException((fail + pass) + " tests: "
                                       + fail + " failure(s), first", first);
        else
            out.format("all %d tests passed%n", fail + pass);
    }
}
