/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.xml.security.test.stax.performance;

import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import java.io.File;
import java.io.FileWriter;
import java.util.*;

/**
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class PerformanceMemoryTest extends AbstractPerformanceTest {

    private static final int runs = 40;
    private static final int xmlResizeFactor = 1000;

    //junit creates for every test method a new class instance so we need a static list
    private static Map<Integer, File> signedFiles = new TreeMap<>();
    private static Map<Integer, File> encryptedFiles = new TreeMap<>();


    @Override
    protected File getTmpFilePath() {
        return new File("target/performanceMemoryTest");
    }

    @Test
    public void testRunFirstOutboundSignatureMemoryPerformance() throws Exception {
        System.out.println("Testing Outbound Signature Memory Performance");
        FileWriter outSignatureSamplesWriter = new FileWriter("target/signatureOutMemorySamples.txt", false);
        for (int i = 1; i <= runs; i++) {
            System.out.println("Run " + i);

            File file = generateLargeXMLFile(i * xmlResizeFactor);

            int startTagCount = countXMLStartTags(file);
            outSignatureSamplesWriter.write("" + startTagCount);

            long startMem = getUsedMemory();
            MemorySamplerThread mst = new MemorySamplerThread(startMem);
            Thread thread = new Thread(mst);
            thread.setPriority(9);
            thread.start();
            File signedFile = doStreamingSignatureOutbound(file, startTagCount);
            mst.setStop(true);
            thread.join();
            outSignatureSamplesWriter.write(" " + mst.getMaxUsedMemory());
            signedFiles.put(startTagCount, signedFile);

            startMem = getUsedMemory();
            mst = new MemorySamplerThread(startMem);
            thread = new Thread(mst);
            thread.setPriority(9);
            thread.start();
            doDOMSignatureOutbound(file, startTagCount);
            mst.setStop(true);
            thread.join();
            outSignatureSamplesWriter.write(" " + mst.getMaxUsedMemory());

            outSignatureSamplesWriter.write("\n");
        }
        outSignatureSamplesWriter.close();
    }

    @Test
    public void testRunSecondInboundSignatureMemoryPerformance() throws Exception {
        System.out.println("Testing Inbound Signature Memory Performance");
        FileWriter inSignatureSamplesWriter = new FileWriter("target/signatureInMemorySamples.txt", false);

        int run = 1;
        Iterator<Map.Entry<Integer, File>> mapIterator = signedFiles.entrySet().iterator();
        while (mapIterator.hasNext()) {
            Map.Entry<Integer, File> entry = mapIterator.next();
            System.out.println("Run " + (run++));

            File file = entry.getValue();
            Integer startTagCount = entry.getKey();
            inSignatureSamplesWriter.write("" + startTagCount);

            long startMem = getUsedMemory();
            MemorySamplerThread mst = new MemorySamplerThread(startMem);
            Thread thread = new Thread(mst);
            thread.setPriority(9);
            thread.start();
            doStreamingSignatureInbound(file, startTagCount);
            mst.setStop(true);
            thread.join();
            inSignatureSamplesWriter.write(" " + mst.getMaxUsedMemory());

            startMem = getUsedMemory();
            mst = new MemorySamplerThread(startMem);
            thread = new Thread(mst);
            thread.setPriority(9);
            thread.start();
            doDOMSignatureInbound(file, startTagCount);
            mst.setStop(true);
            thread.join();
            inSignatureSamplesWriter.write(" " + mst.getMaxUsedMemory());

            inSignatureSamplesWriter.write("\n");
        }
        inSignatureSamplesWriter.close();
    }

    @Test
    public void testRunFirstOutboundEncryptionMemoryPerformance() throws Exception {
        System.out.println("Testing Outbound Encryption Memory Performance");
        FileWriter outEncryptionSamplesWriter = new FileWriter("target/encryptionOutMemorySamples.txt", false);
        for (int i = 1; i <= runs; i++) {
            System.out.println("Run " + i);

            File file = generateLargeXMLFile(i * xmlResizeFactor);

            int startTagCount = countXMLStartTags(file);
            outEncryptionSamplesWriter.write("" + startTagCount);

            long startMem = getUsedMemory();
            MemorySamplerThread mst = new MemorySamplerThread(startMem);
            Thread thread = new Thread(mst);
            thread.setPriority(9);
            thread.start();
            File encryptedFile = doStreamingEncryptionOutbound(file, startTagCount);
            mst.setStop(true);
            thread.join();
            outEncryptionSamplesWriter.write(" " + mst.getMaxUsedMemory());
            encryptedFiles.put(startTagCount, encryptedFile);

            startMem = getUsedMemory();
            mst = new MemorySamplerThread(startMem);
            thread = new Thread(mst);
            thread.setPriority(9);
            thread.start();
            doDOMEncryptionOutbound(file, startTagCount);
            mst.setStop(true);
            thread.join();
            outEncryptionSamplesWriter.write(" " + mst.getMaxUsedMemory());

            outEncryptionSamplesWriter.write("\n");
        }
        outEncryptionSamplesWriter.close();
    }

    @Test
    public void testRunSecondInboundDecryptionMemoryPerformance() throws Exception {
        System.out.println("Testing Inbound Decryption Memory Performance");
        FileWriter inEncryptionSamplesWriter = new FileWriter("target/encryptionInMemorySamples.txt", false);

        int run = 1;
        Iterator<Map.Entry<Integer, File>> mapIterator = encryptedFiles.entrySet().iterator();
        while (mapIterator.hasNext()) {
            Map.Entry<Integer, File> entry = mapIterator.next();
            System.out.println("Run " + (run++));

            File file = entry.getValue();
            Integer startTagCount = entry.getKey();
            inEncryptionSamplesWriter.write("" + startTagCount);

            long startMem = getUsedMemory();
            MemorySamplerThread mst = new MemorySamplerThread(startMem);
            Thread thread = new Thread(mst);
            thread.setPriority(9);
            thread.start();
            doStreamingDecryptionInbound(file, startTagCount);
            mst.setStop(true);
            thread.join();
            inEncryptionSamplesWriter.write(" " + mst.getMaxUsedMemory());

            startMem = getUsedMemory();
            mst = new MemorySamplerThread(startMem);
            thread = new Thread(mst);
            thread.setPriority(9);
            thread.start();
            doDOMDecryptionInbound(file, startTagCount);
            inEncryptionSamplesWriter.write(" " + mst.getMaxUsedMemory());
            mst.setStop(true);
            thread.join();

            inEncryptionSamplesWriter.write("\n");
        }
        inEncryptionSamplesWriter.close();
    }

    private static void gc() {
        System.gc();
        System.runFinalization();
        System.gc();
    }

    private static long getUsedMemory() {
        gc();
        gc();
        long totalMemory = Runtime.getRuntime().totalMemory();
        long freeMemory = Runtime.getRuntime().freeMemory();
        return totalMemory - freeMemory;
    }

    class MemorySamplerThread implements Runnable {

        private long memoryDiff;
        private volatile boolean stop = false;

        private List<Integer> memory = new LinkedList<>();

        MemorySamplerThread(long memoryDiff) {
            this.memoryDiff = memoryDiff;
            System.out.println("memory diff " + memoryDiff / 1024 / 1024);
        }

        public boolean isStop() {
            return stop;
        }

        public void setStop(boolean stop) {
            this.stop = stop;
        }

        @Override
        public void run() {
            int sleepTime = 50;
            while (!isStop()) {
                try {
                    Thread.sleep(sleepTime);
                    if (isStop()) {
                        break;
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                memory.add((int)((getUsedMemory() - memoryDiff) / 1024.0 / 1024.0));
            }
        }

        public int getMaxUsedMemory() {
            System.out.println("Collected " + memory.size() + " samples");
            int maxMem = Integer.MIN_VALUE;
            for (int i = 0; i < memory.size(); i++) {
                int mem = memory.get(i);
                maxMem = mem > maxMem ? mem : maxMem;
            }
            System.out.println("Max memory usage: " + maxMem + "MB");

            if (maxMem > Integer.MIN_VALUE) {
                return maxMem;
            }
            return 0;
        }
    }
}
