package org.apache.maven.plugin.surefire.runorder;
/*
 * 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.
 */

import java.util.List;

import junit.framework.TestCase;

/**
 * @author Kristian Rosenvold
 */
public class ThreadedExecutionSchedulerTest
    extends TestCase
{

    private final RunEntryStatistics a1 = RunEntryStatistics.fromValues( 200, 2, A.class, "at1" );

    private final RunEntryStatistics a2 = RunEntryStatistics.fromValues( 300, 2, A.class, "at2" );

    private final RunEntryStatistics b1 = RunEntryStatistics.fromValues( 400, 2, B.class, "bt1" );

    private final RunEntryStatistics b2 = RunEntryStatistics.fromValues( 300, 2, B.class, "bt2" );

    private final RunEntryStatistics c1 = RunEntryStatistics.fromValues( 400, 2, C.class, "ct1" );

    private final RunEntryStatistics c2 = RunEntryStatistics.fromValues( 200, 2, C.class, "ct2" );

    private final RunEntryStatistics d1 = RunEntryStatistics.fromValues( 401, 2, D.class, "ct2" );

    private final RunEntryStatistics e1 = RunEntryStatistics.fromValues( 200, 2, E.class, "ct2" );

    public void testAddTest()
        throws Exception
    {
        ThreadedExecutionScheduler threadedExecutionScheduler = new ThreadedExecutionScheduler( 2 );
        addPrioritizedTests( threadedExecutionScheduler );
        final List<Class<?>> result = threadedExecutionScheduler.getResult();
        assertEquals( 5, result.size() );
        assertEquals( B.class, result.get( 0 ) );
        assertEquals( C.class, result.get( 1 ) );
        assertEquals( D.class, result.get( 2 ) );
        assertEquals( A.class, result.get( 3 ) );
        assertEquals( E.class, result.get( 4 ) );

    }

    public void testAddTestJaggedResult()
        throws Exception
    {
        ThreadedExecutionScheduler threadedExecutionScheduler = new ThreadedExecutionScheduler( 4 );
        addPrioritizedTests( threadedExecutionScheduler );
        final List result = threadedExecutionScheduler.getResult();
        assertEquals( 5, result.size() );

    }

    private void addPrioritizedTests( ThreadedExecutionScheduler threadedExecutionScheduler )
    {
        threadedExecutionScheduler.addTest( new PrioritizedTest( B.class, createPriority( b1, b2 ) ) );
        threadedExecutionScheduler.addTest( new PrioritizedTest( C.class, createPriority( c1, c2 ) ) );
        threadedExecutionScheduler.addTest( new PrioritizedTest( A.class, createPriority( a1, a2 ) ) );
        threadedExecutionScheduler.addTest( new PrioritizedTest( D.class, createPriority( d1 ) ) );
        threadedExecutionScheduler.addTest( new PrioritizedTest( E.class, createPriority( e1 ) ) );
    }

    private Priority createPriority( RunEntryStatistics runEntryStatistics )
    {
        final Priority priority = new Priority( A.class.getName() );
        priority.addItem( runEntryStatistics );
        return priority;
    }

    private Priority createPriority( RunEntryStatistics runEntryStatistics, RunEntryStatistics runEntryStatistics2 )
    {
        final Priority priority = new Priority( A.class.getName() );
        priority.addItem( runEntryStatistics );
        priority.addItem( runEntryStatistics2 );
        return priority;
    }


    class A
    {
    } // 500 total

    class B
    {
    } // 700 total

    class C
    {
    } // 600  total

    class D
    {
    } // 400 total

    class E
    {
    } // 200 total

}
