package uk.org.skeet.jbench.tasks;

import uk.org.skeet.jbench.*;

import java.util.List;
import java.util.Collections;
import java.util.Random;

/**
 * Very simple implementation of BenchTask. This just
 * sorts a specified number of integers in a specified type
 * of list.
 */
public class ListSort implements BenchTask
{
    private Class listType;
    private int size;

    private List list;
    
    /**
     * Sets the type of list to use, eg java.util.ArrayList
     */
    public void setType (Class listType)
    {
        this.listType=listType;
    }

    /**
     * Sets the size of the test, ie the number of elements
     * to sort
     */
    public void setSize (int size)
    {
        this.size=size;
    }
    
    /**
     * Checks that the configuration is valid
     */
    public void checkConfiguration() throws ConfigurationException
    {
        if (size <= 0)
            throw new ConfigurationException ("Invalid or unset size");
        if (listType==null)
            throw new ConfigurationException ("No collection type set");
        try
        {
            List l = (List) (listType.newInstance());
        }
        catch (Throwable e)
        {
            throw new ConfigurationException ("Unable to instantiate "+listType+
                                              " as a List");
        }
    }
    
    /**
     * Prepares a test by creating and populating a list
     */
    public void prepareTest() throws TaskException
    {
        try
        {
            list = (List) (listType.newInstance());
        }
        catch (Throwable e)
        {
            // Shouldn't happen
            throw new TaskException ("Unable to instantiate "+listType+
                                     " as a List");
        }
        // Always use the same seed for consistency
        Random rng = new Random(100);
        for (int i=0; i < size; i++)
            list.add (new Integer(rng.nextInt (Integer.MAX_VALUE)));
    }

    /**
     * Runs the test itself
     */
    public void runTest()
    {
        Collections.sort (list);
    }
    
    /**
     * Checks the results
     */
    public void checkResults()
        throws TaskException
    {
        for (int i=1; i < size; i++)
        {
            Integer i1 = (Integer) list.get (i-1);
            Integer i2 = (Integer) list.get (i);
            
            if (i1.compareTo (i2) > 0)
                throw new TaskException ("Sort failed: "+i1+" > "+i2);
        }
    }
    
    /**
     * Returns a description of the test, including the parameters
     */
    public String getDescription()
    {
        return "Collections.sort("+listType+") size="+size+" ";
    }
}
