/*
 * 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 freemarker.ext.beans;

import org.junit.internal.runners.JUnit38ClassRunner;
import org.junit.runner.RunWith;

import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateNumberModel;
import junit.framework.TestCase;

@RunWith(JUnit38ClassRunner.class)
public abstract class AbstractParallelIntrospectionTest extends TestCase {
    
    private static final int NUM_THREADS = 8;
    private static final int NUM_ENTITYES = 8;
    private static final int NUM_MEMBERS = 8;
    private static final int ITERATIONS = 20000;
    private static final double CACHE_CLEARING_CHANCE = 0.01;
    
    private BeansWrapper beansWrapper = new BeansWrapper();
    
    public AbstractParallelIntrospectionTest(String name) {
        super(name);
    }
    
    public void testReliability() {
        testReliability(ITERATIONS);
    }
    
    public void testReliability(int iterations) {
        TestThread[] ts = new TestThread[NUM_THREADS]; 
        for (int i = 0; i < NUM_THREADS; i++) {
            ts[i] = new TestThread(iterations);
            ts[i].start();
        }

        for (int i = 0; i < NUM_THREADS; i++) {
            try {
                ts[i].join();
                if (ts[i].error != null) {
                    throw new AssertionError(ts[i].error);
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    protected abstract TemplateHashModel getWrappedEntity(int objIdx) throws TemplateModelException;
    
    protected final BeansWrapper getBeansWrapper() {
        return beansWrapper;
    }
    
    private class TestThread extends Thread {
        
        private final int iterations;
        
        private Throwable error;
        
        private TestThread(int iterations) {
            this.iterations = iterations;
        }

        @Override
        public void run() {
            try {
                for (int i = 0; i < iterations; i++) {
                    if (Math.random() < CACHE_CLEARING_CHANCE) {
                        beansWrapper.clearClassIntrospectionCache();
                    }
                    int objIdx = (int) (Math.random() * NUM_ENTITYES);
                    TemplateHashModel h = getWrappedEntity(objIdx);
                    int mIdx = (int) (Math.random() * NUM_MEMBERS);
                    testProperty(h, objIdx, mIdx);
                    testMethod(h, objIdx, mIdx);
                }
            } catch (Throwable e) {
                error = e;
            }
        }

        private void testProperty(TemplateHashModel h, int objIdx, int mIdx)
                throws TemplateModelException, AssertionError {
            TemplateNumberModel pv = (TemplateNumberModel) h.get("p" + mIdx);
            final int expected = objIdx * 1000 + mIdx;
            final int got = pv.getAsNumber().intValue();
            if (got != expected) {
                throw new AssertionError("Property assertation failed; " +
                        "expected " + expected + ", but got " + got);
            }
        }

        private void testMethod(TemplateHashModel h, int objIdx, int mIdx)
                throws TemplateModelException, AssertionError {
            TemplateMethodModel pv = (TemplateMethodModel) h.get("m" + mIdx);
            final int expected = objIdx * 1000 + mIdx;
            final int got = ((TemplateNumberModel) pv.exec(null)).getAsNumber().intValue();
            if (got != expected) {
                throw new AssertionError("Method assertation failed; " +
                        "expected " + expected + ", but got " + got);
            }
        }
        
    }

}
