/*
 * 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.
 */
#if !defined(TESTHARNESS_HEADER_GUARD_1357924680)
#define TESTHARNESS_HEADER_GUARD_1357924680

// Base header file.  Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>



#include <climits>
#include <fstream>
#include <sstream>



#include <xalanc/Include/XalanMemoryManagement.hpp>
#include <xalanc/Include/XalanVector.hpp>
#include <xalanc/Include/XalanMap.hpp>



#include <xalanc/PlatformSupport/DOMStringHelper.hpp>



#include <xalanc/XalanDOM/XalanNode.hpp>
#include <xalanc/XalanDOM/XalanDOMString.hpp>



#include <xalanc/Harness/XalanFileUtility.hpp>
#include <xalanc/Harness/XalanXMLFileReporter.hpp>



#include "Utils.hpp"
#include "Logger.hpp"
#include "Timer.hpp"



using xalanc::XalanMemMgrs;
using xalanc::XalanVector;
using xalanc::XalanMap;
using xalanc::XalanNode;
using xalanc::XalanDOMString;
using xalanc::XalanFileUtility;
using xalanc::XalanXMLFileReporter;



/**
 * Processor interface options
 */
struct ProcessorOptions
{
    XalanNode*  initOptions;
    XalanNode*  compileOptions;
    XalanNode*  parseOptions;
    XalanNode*  resultOptions;
    XalanNode*  transformOptions;

    ProcessorOptions() :
            initOptions(0),
            compileOptions(0),
            parseOptions(0),
            resultOptions(0),
            transformOptions(0)
    {
    }
};



/**
 * Test case
 */
class TestCase
{
public:
    
    TestCase();

    TestCase(const TestCase& theRhs);

    XalanDOMString  stylesheet;
    XalanDOMString  inputDocument;
    XalanDOMString  resultDocument;
    XalanDOMString  resultDirectory;
    XalanDOMString  goldResult;
    long            numIterations;
    long            minTimeToExecute;
    bool            verifyResult;
    XalanDOMString  inputMode;

    typedef XalanMap<XalanDOMString, ProcessorOptions>  ProcessorOptionsMap;

    ProcessorOptionsMap processorOptions;
};



typedef TestCase                    TestCaseType;
typedef XalanVector<TestCaseType>   TestCasesType;



/**
 *  Test harness
 */
template <class Processor>
class TestHarness
{
public:

    typedef typename Processor::CompiledStylesheetType  CompiledStylesheetType;
    typedef typename Processor::ParsedInputSourceType   ParsedInputSourceType;
    typedef typename Processor::ResultTargetType        ResultTargetType;

    typedef typename XalanXMLFileReporter::Hashtable    TestAttributesType;

    TestHarness();

    void init(
            XalanFileUtility&       fileUtility,
            XalanXMLFileReporter&   reporter,
            Logger&                 logger);

    void terminate();

    void executeTestCase(const TestCaseType& testCase);

    void executeTestCases(const TestCasesType& testCases);


protected:

    Processor m_processor;

    XalanFileUtility*       m_fileUtility;

    XalanXMLFileReporter*   m_reporter;

    Logger*                 m_logger;
};



template <class Processor>
void
TestHarness<Processor>::executeTestCases(const TestCasesType& testCases)
{
    TestCasesType::const_iterator testCaseIter = testCases.begin();
    while (testCaseIter != testCases.end())
    {
        executeTestCase(*testCaseIter);
        ++testCaseIter;
    }
}



template <class Processor>
void
TestHarness<Processor>::executeTestCase(const TestCaseType& testCase)
{
    TestAttributesType testAttributes(XalanMemMgrs::getDefaultXercesMemMgr());
    
    testAttributes.insert(TestAttributesType::value_type(XalanDOMString("stylesheet"), testCase.stylesheet));
    testAttributes.insert(TestAttributesType::value_type(XalanDOMString("input-document"), testCase.inputDocument));

    try {

        CompiledStylesheetType  compiledStylesheet = 0;
        ParsedInputSourceType   parsedInputSource = 0;

        static const ProcessorOptions defaultProcessor;
        
        TestCase::ProcessorOptionsMap::const_iterator iter = testCase.processorOptions.find(m_processor.getName());

        const ProcessorOptions&  processor = iter != testCase.processorOptions.end() ? iter->second : defaultProcessor;

        m_fileUtility->checkAndCreateDir(testCase.resultDirectory);

        Timer timeCompile;

        if (testCase.inputMode == XalanDOMString("stream"))
        {
            using std::istringstream;

            istringstream compilerStream; 
            fileToStream(testCase.stylesheet, compilerStream);
            timeCompile.start();
            compiledStylesheet = m_processor.compileStylesheet(
                    compilerStream,
                    processor.compileOptions);
            timeCompile.stop();
        }
        else if (testCase.inputMode == XalanDOMString("file"))
        {
            timeCompile.start();
            compiledStylesheet = m_processor.compileStylesheet(
                    testCase.stylesheet,
                    processor.compileOptions);
            timeCompile.stop();
        }
        else 
        {
            using std::endl;

            m_logger->error() 
                    << "Mode: " 
                    << testCase.inputMode.c_str()
                    << " is invalid for stylesheet: "
                    << testCase.stylesheet
                    << endl;
        }

        m_reporter->addMetricToAttrs("compile-xsl", timeCompile.getElapsedTime(), testAttributes);

        long numIterations = 0;

        long totalParseInputTime = 0;
        long minParseInputTime = LONG_MAX;
        long maxParseInputTime = 0 ;

        long totalTransformTime = 0;
        long minTransformTime = LONG_MAX;
        long maxTransformTime = 0;


        Timer timeTotalRun;
        timeTotalRun.start();

        while (compiledStylesheet &&
               numIterations < testCase.numIterations &&
               timeTotalRun.getElapsedTime() < testCase.minTimeToExecute)
        {
            Timer timeInput;
            if (testCase.inputMode == XalanDOMString("stream") &&
                !parsedInputSource)
            {
                using std::istringstream;

                istringstream inputStream;
                fileToStream(testCase.inputDocument, inputStream);

                timeInput.start();
                parsedInputSource = m_processor.parseInputSource(
                        inputStream, 
                        processor.parseOptions);
                timeInput.stop();
            }
            else if (testCase.inputMode == XalanDOMString("file"))
            {
                timeInput.start();
                parsedInputSource = m_processor.parseInputSource(
                        testCase.inputDocument, 
                        processor.parseOptions);
                timeInput.stop();
            }
            else
            {
                using std::endl;

                m_logger->error() 
                    << "Mode: " 
                    << testCase.inputMode.c_str()
                    << " is inavlid for input document: "
                    << testCase.inputDocument
                    << endl;
                break;
            }

            totalParseInputTime += timeInput.getElapsedTime();
            minParseInputTime = timeInput.getElapsedTime() < minParseInputTime ? timeInput.getElapsedTime() : minParseInputTime;
            maxParseInputTime = timeInput.getElapsedTime() > maxParseInputTime ? timeInput.getElapsedTime() : maxParseInputTime;


            ResultTargetType    resultTarget =
                m_processor.createResultTarget(
                    testCase.resultDocument, 
                    processor.resultOptions);

            Timer timeTransform;
            timeTransform.start();
            m_processor.transform(
                    compiledStylesheet,
                    parsedInputSource,
                    resultTarget);
            timeTransform.stop();

            totalTransformTime += timeTransform.getElapsedTime();
            minTransformTime = timeTransform.getElapsedTime() < minTransformTime ? timeTransform.getElapsedTime() : minTransformTime;
            maxTransformTime = timeTransform.getElapsedTime() > maxTransformTime ? timeTransform.getElapsedTime() : maxTransformTime;

            ++numIterations;
            m_processor.releaseResultTarget(resultTarget);
        }

        timeTotalRun.stop();

        if (compiledStylesheet)
        {
            m_processor.releaseStylesheet(compiledStylesheet);
        }

        if (parsedInputSource)
        {
            m_processor.releaseInputSource(parsedInputSource);
        }

        if (true == testCase.verifyResult)
        {
            testAttributes.insert(TestAttributesType::value_type(XalanDOMString("verify"), XalanDOMString("yes")));
            if (checkFileExists(testCase.resultDocument))
            {
                if (checkFileExists(testCase.goldResult))
                {
                    if (m_fileUtility->compareSerializedResults(
                            testCase.resultDocument,
                            testCase.goldResult))
                    {
                        testAttributes.insert(TestAttributesType::value_type(XalanDOMString("result"), XalanDOMString("pass")));
                    }
                    else
                    {
                        testAttributes.insert(TestAttributesType::value_type(XalanDOMString("result"), XalanDOMString("fail")));
                    }
                }
                else
                {
                    testAttributes.insert(TestAttributesType::value_type(XalanDOMString("result"), XalanDOMString("incomplete")));
                }
            }
            else
            {
                testAttributes.insert(TestAttributesType::value_type(XalanDOMString("result"), XalanDOMString("incomplete")));
            }
        }
        else
        {
            testAttributes.insert(TestAttributesType::value_type(XalanDOMString("verify"), XalanDOMString("no")));
        }


        m_reporter->addMetricToAttrs("num-iterations", numIterations, testAttributes);
        m_reporter->addMetricToAttrs("elapsed-time", timeTotalRun.getElapsedTime(), testAttributes);
        m_reporter->addMetricToAttrs("min-parse-input", minParseInputTime, testAttributes);
        m_reporter->addMetricToAttrs("max-parse-input", maxParseInputTime, testAttributes);
        m_reporter->addMetricToAttrs("avg-parse-input", totalParseInputTime / numIterations, testAttributes);
        m_reporter->addMetricToAttrs("min-transform", minTransformTime, testAttributes);
        m_reporter->addMetricToAttrs("max-transform", maxTransformTime, testAttributes);
        m_reporter->addMetricToAttrs("avg-transform", totalTransformTime / numIterations, testAttributes);

        testAttributes.insert(TestAttributesType::value_type(XalanDOMString("complete"), XalanDOMString("yes")));

    }
    catch (const XalanDOMString& exception)
    {
        using std::endl;

        m_logger->error()  
                << "Error encountered during transformation: "
                << testCase.stylesheet.c_str()
                << ", error: "
                << exception.c_str()
                << endl;

        testAttributes.insert(TestAttributesType::value_type(XalanDOMString("complete"), XalanDOMString("no")));
    }
    catch (int)
    {
        testAttributes.insert(TestAttributesType::value_type(XalanDOMString("complete"), XalanDOMString("no")));
    }

    m_reporter->logElementWAttrs(1, "testcase", testAttributes, "");
}



template <class Processor>
TestHarness<Processor>::TestHarness()
{

}


template <class Processor>
void 
TestHarness<Processor>::init(
        XalanFileUtility&       fileUtility,
        XalanXMLFileReporter&   reporter,
        Logger&                 logger)
{
    m_processor.init();

    m_fileUtility = &fileUtility;

    m_reporter = &reporter;

    m_logger = &logger;
}



template <class Processor>
void
TestHarness<Processor>::terminate()
{
   m_processor.terminate(); 
}


#endif // TESTHARNESS_HEADER_GUARD_1357924680
