#ifndef _TCUTESTCASE_HPP
#define _TCUTESTCASE_HPP
/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed 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.
 *
 *//*!
 * \file
 * \brief Base class for a test case.
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "tcuTestContext.hpp"

#include <string>
#include <vector>

namespace tcu
{

enum TestNodeType
{
    NODETYPE_ROOT = 0,      //!< Root for all test packages.
    NODETYPE_PACKAGE,       //!< Test case package -- same as group, but is omitted from XML dump.
    NODETYPE_GROUP,         //!< Test case container -- cannot be executed.
    NODETYPE_SELF_VALIDATE, //!< Self-validating test case -- can be executed
    NODETYPE_PERFORMANCE,   //!< Performace test case -- can be executed
    NODETYPE_CAPABILITY,    //!< Capability score case -- can be executed
    NODETYPE_ACCURACY       //!< Accuracy test case -- can be executed
};

enum TestNodeClass
{
    NODECLASS_GROUP = 0,  //!< Root or non-leaf in the test hierarchy tree
    NODECLASS_EXECUTABLE, //!< Non-root leaf in the test hierarchy tree

    NODECLASS_LAST
};

inline TestNodeClass getTestNodeTypeClass(TestNodeType type)
{
    switch (type)
    {
    case NODETYPE_ROOT:
        return NODECLASS_GROUP;
    case NODETYPE_PACKAGE:
        return NODECLASS_GROUP;
    case NODETYPE_GROUP:
        return NODECLASS_GROUP;
    case NODETYPE_SELF_VALIDATE:
        return NODECLASS_EXECUTABLE;
    case NODETYPE_PERFORMANCE:
        return NODECLASS_EXECUTABLE;
    case NODETYPE_CAPABILITY:
        return NODECLASS_EXECUTABLE;
    case NODETYPE_ACCURACY:
        return NODECLASS_EXECUTABLE;
    default:
        DE_ASSERT(false);
        return NODECLASS_LAST;
    }
}

inline bool isTestNodeTypeExecutable(TestNodeType type)
{
    return getTestNodeTypeClass(type) == NODECLASS_EXECUTABLE;
}

inline bool isValidTestCaseNameChar(char c)
{
    return de::inRange(c, 'a', 'z') || de::inRange(c, 'A', 'Z') || de::inRange(c, '0', '9') || c == '_' || c == '-';
}

/*--------------------------------------------------------------------*//*!
 * \brief Test case hierarchy node
 *
 * Test node forms the backbone of the test case hierarchy. All objects
 * in the hierarchy are derived from this class.
 *
 * Each test node has a type and all except the root node have name and
 * description. Root and test group nodes have a list of children.
 *
 * During test execution TestExecutor iterates the hierarchy. Upon entering
 * the node (both groups and test cases) init() is called. When exiting the
 * node deinit() is called respectively.
 *//*--------------------------------------------------------------------*/
class TestNode
{
public:
    enum IterateResult
    {
        STOP     = 0,
        CONTINUE = 1
    };

    // Methods.
    TestNode(TestContext &testCtx, TestNodeType nodeType, const char *name, const char *description);
    TestNode(TestContext &testCtx, TestNodeType nodeType, const char *name, const char *description,
             const std::vector<TestNode *> &children);
    virtual ~TestNode(void);

    TestNodeType getNodeType(void) const
    {
        return m_nodeType;
    }
    TestContext &getTestContext(void) const
    {
        return m_testCtx;
    }
    const char *getName(void) const
    {
        return m_name.c_str();
    }
    const char *getDescription(void) const
    {
        return m_description.c_str();
    }
    void getChildren(std::vector<TestNode *> &children);
    void addChild(TestNode *node);

    virtual void init(void);
    virtual void deinit(void);
    virtual IterateResult iterate(void) = 0;

protected:
    TestContext &m_testCtx;
    std::string m_name;
    std::string m_description;

private:
    const TestNodeType m_nodeType;
    std::vector<TestNode *> m_children;
};

/*--------------------------------------------------------------------*//*!
 * \brief Test case group node
 *
 * Test case group implementations must inherit this class. To save resources
 * during test execution the group must delay creation of any child groups
 * until init() is called.
 *
 * Default deinit() for test group will destroy all child nodes.
 *//*--------------------------------------------------------------------*/
class TestCaseGroup : public TestNode
{
public:
    TestCaseGroup(TestContext &testCtx, const char *name, const char *description);
    TestCaseGroup(TestContext &testCtx, const char *name, const char *description,
                  const std::vector<TestNode *> &children);
    virtual ~TestCaseGroup(void);

    virtual IterateResult iterate(void);
};

/*--------------------------------------------------------------------*//*!
 * \brief Test case class
 *
 * Test case implementations must inherit this class.
 *
 * Test case objects are usually constructed when TestExecutor enters parent
 * group. Allocating any non-parameter resources, especially target API objects
 * must be delayed to init().
 *
 * Upon entering the test case TestExecutor calls init(). If initialization
 * is successful (no exception is thrown) the executor will then call iterate()
 * until test case returns STOP. After that deinit() will be called.
 *
 * Before exiting the execution phase (i.e. at returning STOP from iterate())
 * the test case must set valid status code to test context (m_testCtx).
 *
 * Test case can also signal error condition by throwing an exception. In
 * that case the framework will set result code and details based on the
 * exception.
 *//*--------------------------------------------------------------------*/
class TestCase : public TestNode
{
public:
    TestCase(TestContext &testCtx, const char *name, const char *description);
    TestCase(TestContext &testCtx, TestNodeType nodeType, const char *name, const char *description);
    virtual ~TestCase(void);
};

class TestStatus
{
public:
    TestStatus(qpTestResult code, const std::string &description) : m_code(code), m_description(description)
    {
    }

    bool isComplete(void) const
    {
        return m_code != QP_TEST_RESULT_LAST;
    }
    qpTestResult getCode(void) const
    {
        DE_ASSERT(isComplete());
        return m_code;
    }
    const std::string &getDescription(void) const
    {
        DE_ASSERT(isComplete());
        return m_description;
    }

    static TestStatus pass(const std::string &description)
    {
        return TestStatus(QP_TEST_RESULT_PASS, description);
    }
    static TestStatus fail(const std::string &description)
    {
        return TestStatus(QP_TEST_RESULT_FAIL, description);
    }
    static TestStatus incomplete(void)
    {
        return TestStatus(QP_TEST_RESULT_LAST, "");
    }

private:
    qpTestResult m_code;
    std::string m_description;
} DE_WARN_UNUSED_TYPE;

} // namespace tcu

#endif // _TCUTESTCASE_HPP
