/*
 * Copyright (c) 2008, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Chris Delahunt
//       - Bug 318187 - NegativeArraySizeException on JCEEncryptor.decryptPassword()
package org.eclipse.persistence.testing.tests.simultaneous;

import org.eclipse.persistence.testing.framework.AutoVerifyTestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.internal.security.JCEEncryptor;

/**
 * @author Chris Delahunt
 * @date June 26, 2003
 *  Test fix for 318187:
 *  java.lang.NegativeArraySizeException is thrown when threads concurrently access the
 *  JCEEncryptor.decrypt(password)
 *
 */
public class ConcurrentDecryptionTest extends AutoVerifyTestCase {
    //used to signal the threads to stop, accessed directly from the threads
    public boolean run;
    public Exception error;

    //number of concurrent threads to use
    public int threadCount = 100;
    //password to encrypt
    public String password = "test1";
    //wait time for the error to occur
    public int sleepTime = 8000;

    //accessed directly from the threads
    private JCEEncryptor encryptor;
    private String encryptedPassword;


    @Override
    protected void setup() throws Throwable {
        encryptor = new JCEEncryptor();
        encryptedPassword = encryptor.encryptPassword(password);
    }

    @Override
    protected void test() throws Throwable {
        run = true;
        error = null;
        try {
            Thread[] thread = new Thread[threadCount];
            for(int i=0; i<threadCount; i++) {
                thread[i]=new Thread(new Runner1(this));
            }
            for(int i=0;i<threadCount; i++){
                thread[i].start();
            }
            try {
                Thread.sleep(sleepTime);
            } catch (InterruptedException e) {
                //exception could be ignored
                e.printStackTrace();
            }
        } finally {
            //set the flag so started threads will end.
            run = false;
        }
    }

    @Override
    protected void verify() throws Throwable {
        if (error!=null){
            throw new TestErrorException("error encountered: "+error, error);
        }
    }

    //runnable that repeatedly calls decryptPassword until the run flag is set to false
    class Runner1 implements Runnable {
        protected ConcurrentDecryptionTest concurrentDecryptionTest;
        public Runner1(ConcurrentDecryptionTest concurrentDecryptionTest) {
            this.concurrentDecryptionTest = concurrentDecryptionTest;
        }
        @Override
        public void run() {
            try {
                while (concurrentDecryptionTest.run && (concurrentDecryptionTest.error == null) ){
                    concurrentDecryptionTest.encryptor.decryptPassword(concurrentDecryptionTest.encryptedPassword);
                }
            } catch (Exception e){
                concurrentDecryptionTest.run = false;
                concurrentDecryptionTest.error = e;
            }
        }
    }

}
