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

import java.nio.ByteBuffer;
import java.util.Properties;

public class LimitDirectMemory {
    private static final int K = 1024;

    public static void main(String [] args) throws Exception {
        if (args.length < 2)
            throw new RuntimeException();
        boolean throwp = parseThrow(args[0]);
        int size = parseSize(args[1]);
        int incr = (args.length > 2 ? parseSize(args[2]) : size);

        Properties p = System.getProperties();
        if (p.getProperty("sun.nio.MaxDirectMemorySize") != null)
            throw new RuntimeException("sun.nio.MaxDirectMemorySize defined");

        ByteBuffer [] b = new ByteBuffer[K];

        // Fill up most/all of the direct memory
        int i = 0;
        while (size >= incr) {
            b[i++] = ByteBuffer.allocateDirect(incr);
            size -= incr;
        }

        if (throwp) {
            try {
                b[i] = ByteBuffer.allocateDirect(incr);
                throw new RuntimeException("OutOfMemoryError not thrown: "
                                           + incr);
            } catch (OutOfMemoryError e) {
                e.printStackTrace(System.out);
                System.out.println("OK - Error thrown as expected ");
            }
        } else {
            b[i] = ByteBuffer.allocateDirect(incr);
            System.out.println("OK - Error not thrown");
        }
    }

    private static boolean parseThrow(String s) {
        if (s.equals("true"))  return true;
        if (s.equals("false")) return false;
        throw new RuntimeException("Unrecognized expectation: " + s);
    }

    private static int parseSize(String size) throws Exception {

        if (size.equals("DEFAULT"))
            return (int)Runtime.getRuntime().maxMemory();
        if (size.equals("DEFAULT+1"))
            return (int)Runtime.getRuntime().maxMemory() + 1;
        if (size.equals("DEFAULT+1M"))
            return (int)Runtime.getRuntime().maxMemory() + (1 << 20);
        if (size.equals("DEFAULT-1"))
            return (int)Runtime.getRuntime().maxMemory() - 1;
        if (size.equals("DEFAULT/2"))
            return (int)Runtime.getRuntime().maxMemory() / 2;

        int idx = 0, len = size.length();


        for (int i = 0; i < len; i++) {
            if (Character.isDigit(size.charAt(i))) idx++;
            else break;
        }

        if (idx == 0)
            throw new RuntimeException("No digits detected: " + size);

        int result = Integer.parseInt(size.substring(0, idx));

        if (idx < len) {
            for (int i = idx; i < len; i++) {
                switch(size.charAt(i)) {
                case 'T': case 't': result *= K; // fall through
                case 'G': case 'g': result *= K; // fall through
                case 'M': case 'm': result *= K; // fall through
                case 'K': case 'k': result *= K;
                    break;
                default:
                    throw new RuntimeException("Unrecognized size: " + size);
                }
            }
        }
        return result;
    }
}
