/* ====================================================================
   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 org.apache.poi.ss.excelant;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.function.Supplier;

import org.apache.poi.ss.excelant.util.ExcelAntEvaluationResult;
import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtil;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;

/**
 * This class represents a single test.  In order for the test any and all
 * ExcelAntEvaluateCell evaluations must pass.  Therefore it is recommended
 * that you use only 1 evaluator but you can use more if you choose.
 */
@SuppressWarnings("unused")
public class ExcelAntTest extends Task{
    private LinkedList<ExcelAntEvaluateCell> evaluators;

    private LinkedList<Task> testTasks;

    private String name;

    private double globalPrecision;

    private boolean showSuccessDetails;

    private boolean showFailureDetail;
    LinkedList<String> failureMessages;


    private ExcelAntWorkbookUtil workbookUtil;

    private boolean passed = true;


    public ExcelAntTest() {
        evaluators = new LinkedList<>();
        failureMessages = new LinkedList<>();
        testTasks = new LinkedList<>();
    }

    public void setPrecision( double precision ) {
        globalPrecision = precision;
    }

    public void setWorkbookUtil( ExcelAntWorkbookUtil wbUtil ) {
        workbookUtil = wbUtil;
    }


    public void setShowFailureDetail( boolean value ) {
        showFailureDetail = value;
    }

    public void setName( String nm ) {
        name = nm;
    }

    public String getName() {
        return name;
    }

    public void setShowSuccessDetails( boolean details ) {
        showSuccessDetails = details;
    }

    public boolean showSuccessDetails() {
        return showSuccessDetails;
    }

    public void addSetDouble( ExcelAntSetDoubleCell setter ) {
        addSetter( setter );
    }

    public void addSetString( ExcelAntSetStringCell setter ){
        addSetter( setter );
    }

    public void addSetFormula( ExcelAntSetFormulaCell setter ) {
        addSetter( setter );
    }

    public void addHandler( ExcelAntHandlerTask handler ) {
        testTasks.add( handler );
    }

    private void addSetter( ExcelAntSet setter ) {
        testTasks.add( setter );
    }

    public void addEvaluate( ExcelAntEvaluateCell evaluator ) {
        testTasks.add( evaluator );
    }

    protected LinkedList<ExcelAntEvaluateCell> getEvaluators() {
        return evaluators;
    }

    @Override
    public void execute() throws BuildException {

        Iterator<Task> taskIt = testTasks.iterator();

        int testCount = evaluators.size();
        int failureCount = 0;

        // roll over all sub task elements in one loop.  This allows the
        // ordering of the sub elements to be considered.
        while( taskIt.hasNext() ) {
            Task task = taskIt.next();

           // log( task.getClass().getName(), Project.MSG_INFO );

            if( task instanceof ExcelAntSet ) {
                ExcelAntSet set = (ExcelAntSet) task;
                set.setWorkbookUtil(workbookUtil);
                set.execute();
            }

            if( task instanceof ExcelAntHandlerTask ) {
                ExcelAntHandlerTask handler = (ExcelAntHandlerTask)task;
                handler.setEAWorkbookUtil(workbookUtil );
                handler.execute();
            }

            if (task instanceof ExcelAntEvaluateCell ) {
                ExcelAntEvaluateCell eval = (ExcelAntEvaluateCell)task;
                eval.setWorkbookUtil( workbookUtil );

                if( globalPrecision > 0 ) {
                    log( "setting globalPrecision to " + globalPrecision + " in the evaluator", Project.MSG_VERBOSE );
                    eval.setGlobalPrecision( globalPrecision );
                }

                try {
                    eval.execute();
                    ExcelAntEvaluationResult result = eval.getResult();

                    Supplier<String> details = () ->
                        result.getCellName() + ".  It evaluated to " +
                        result.getReturnValue() + " when the value of " +
                        eval.getExpectedValue() + " with precision of " +
                        eval.getPrecision();

                    if( result.didTestPass() && !result.evaluationCompleteWithError()) {
                        if(showSuccessDetails) {
                            log("Succeeded when evaluating " + details.get(), Project.MSG_INFO );
                        }
                    } else {
                        if(showFailureDetail) {
                            failureMessages.add( "\tFailed to evaluate cell " + details.get() + " was expected." );
                        }
                        passed = false;
                        failureCount++;

                        if(eval.requiredToPass()) {
                            throw new BuildException( "\tFailed to evaluate cell " + details.get() + " was expected." );
                        }
                    }
                } catch( NullPointerException npe ) {
                    // this means the cell reference in the test is bad.
                    log( "Cell assignment " + eval.getCell() + " in test " + getName() +
                          " appears to point to an empy cell.  Please check the " +
                          " reference in the ant script.", Project.MSG_ERR );
                }
            }
        }

        if(!passed) {
            log( "Test named " + name + " failed because " + failureCount +
                     " of " + testCount + " evaluations failed to " +
                     "evaluate correctly.",
                     Project.MSG_ERR );
            if(showFailureDetail && failureMessages.size() > 0 ) {
                for (String failureMessage : failureMessages) {
                    log(failureMessage, Project.MSG_ERR);
                }
            }
        }
    }

    public boolean didTestPass() {

        return passed;
    }
 }
