/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.test;

import lombok.experimental.UtilityClass;

import java.io.File;
import java.io.IOException;
import java.util.function.Function;
import net.ranides.assira.junit.TestContractRunner;
import net.ranides.assira.reflection.util.ClassLoaderUtils;
import net.ranides.assira.reflection.util.PackageScanner;
import net.ranides.assira.system.RuntimeUtils;
import net.ranides.assira.trace.ExceptionUtils;

/**
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
@UtilityClass
public final class ContractTesters {

    public static TestContractRunner runner() {
        return new TestContractRunner(Li.RUNNER);
    }

    private static final class Li { // NOPMD - lazy init idiom
        
        private static final TestContractRunner RUNNER;
        
        static {
            try {
                RUNNER = new TestContractRunner(System.err);
                
                PackageScanner.scanner().scope("net.ranides").names()
                    .map(newTester())
                    .filter(o -> o!=null)
                    .forEach(RUNNER::append);

            } catch(IOException cause) {
                throw ExceptionUtils.rethrow(cause);
            }
        }

        private static Function<String, Object> newTester() {
            ClassLoader loader = ClassLoaderUtils.getDefault();
            return name -> {
                try {
                    return name.endsWith("Tester") ? Class.forName(name, false, loader).newInstance() : null;
                } catch(ReflectiveOperationException cause) {
                    return null;
                }
            };
        }

    }

}
