/*-------------------------------------------------------------------------
 * drawElements Quality Program Test Executor
 * ------------------------------------------
 *
 * 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 Test case.
 *//*--------------------------------------------------------------------*/

#include "xeTestCase.hpp"

using std::vector;

namespace xe
{

const char *getTestCaseTypeName(TestCaseType caseType)
{
    switch (caseType)
    {
    case TESTCASETYPE_SELF_VALIDATE:
        return "SelfValidate";
    case TESTCASETYPE_CAPABILITY:
        return "Capability";
    case TESTCASETYPE_ACCURACY:
        return "Accuracy";
    case TESTCASETYPE_PERFORMANCE:
        return "Performance";
    default:
        DE_ASSERT(false);
        return DE_NULL;
    }
}

static inline int getFirstComponentLength(const char *path)
{
    int compLen = 0;
    while (path[compLen] != 0 && path[compLen] != '.')
        compLen++;
    return compLen;
}

static bool compareNameToPathComponent(const char *name, const char *path, int compLen)
{
    for (int pos = 0; pos < compLen; pos++)
    {
        if (name[pos] != path[pos])
            return false;
    }

    if (name[compLen] != 0)
        return false;

    return true;
}

static void splitPath(const char *path, std::vector<std::string> &components)
{
    std::string pathStr(path);
    int compStart = 0;

    for (int pos = 0; pos < (int)pathStr.length(); pos++)
    {
        if (pathStr[pos] == '.')
        {
            components.push_back(pathStr.substr(compStart, pos - compStart));
            compStart = pos + 1;
        }
    }

    DE_ASSERT(compStart < (int)pathStr.length());
    components.push_back(pathStr.substr(compStart));
}

// TestNode

TestNode::TestNode(TestGroup *parent, TestNodeType nodeType, const char *name, const char *desc)
    : m_parent(parent)
    , m_nodeType(nodeType)
    , m_name(name)
    , m_description(desc)
{
    if (m_parent)
    {
        // Verify that the name is unique.
        if (parent->m_childNames.find(name) != parent->m_childNames.end())
            throw Error(std::string("Duplicate node '") + name + "' in '" + parent->getFullPath());

        m_parent->m_children.push_back(this);
        m_parent->m_childNames.insert(name);
    }
}

void TestNode::getFullPath(std::string &dst) const
{
    dst.clear();

    int nameLen             = 0;
    const TestNode *curNode = this;

    for (;;)
    {
        nameLen += (int)curNode->m_name.length();

        DE_ASSERT(curNode->m_parent);
        if (curNode->m_parent->getNodeType() != TESTNODETYPE_ROOT)
        {
            nameLen += 1;
            curNode = curNode->m_parent;
        }
        else
            break;
    }

    dst.resize(nameLen);

    curNode = this;
    int pos = nameLen;

    for (;;)
    {
        std::copy(curNode->m_name.begin(), curNode->m_name.end(), dst.begin() + (pos - curNode->m_name.length()));
        pos -= (int)curNode->m_name.length();

        DE_ASSERT(curNode->m_parent);
        if (curNode->m_parent->getNodeType() != TESTNODETYPE_ROOT)
        {
            dst[--pos] = '.';
            curNode    = curNode->m_parent;
        }
        else
            break;
    }
}

const TestNode *TestNode::find(const char *path) const
{
    if (m_nodeType == TESTNODETYPE_ROOT)
    {
        // Don't need to consider current node.
        return static_cast<const TestGroup *>(this)->findChildNode(path);
    }
    else
    {
        // Check if first component matches this node.
        int compLen = getFirstComponentLength(path);
        XE_CHECK(compLen > 0);

        if (compareNameToPathComponent(getName(), path, compLen))
        {
            if (path[compLen] == 0)
                return this;
            else if (getNodeType() == TESTNODETYPE_GROUP)
                return static_cast<const TestGroup *>(this)->findChildNode(path + compLen + 1);
            else
                return DE_NULL;
        }
        else
            return DE_NULL;
    }
}

TestNode *TestNode::find(const char *path)
{
    return const_cast<TestNode *>(const_cast<const TestNode *>(this)->find(path));
}

// TestGroup

TestGroup::TestGroup(TestGroup *parent, TestNodeType nodeType, const char *name, const char *description)
    : TestNode(parent, nodeType, name, description)
{
    DE_ASSERT(nodeType == TESTNODETYPE_GROUP || nodeType == TESTNODETYPE_ROOT);
    DE_ASSERT(!parent == (nodeType == TESTNODETYPE_ROOT));
}

TestGroup::~TestGroup(void)
{
    for (std::vector<TestNode *>::iterator i = m_children.begin(); i != m_children.end(); i++)
        delete *i;
}

TestGroup *TestGroup::createGroup(const char *name, const char *description)
{
    return new TestGroup(this, TESTNODETYPE_GROUP, name, description);
}

TestCase *TestGroup::createCase(TestCaseType caseType, const char *name, const char *description)
{
    return TestCase::createAsChild(this, caseType, name, description);
}

const TestNode *TestGroup::findChildNode(const char *path) const
{
    int compLen = getFirstComponentLength(path);
    XE_CHECK(compLen > 0);

    // Try to find matching children.
    const TestNode *matchingNode = DE_NULL;
    for (vector<TestNode *>::const_iterator iter = m_children.begin(); iter != m_children.end(); iter++)
    {
        if (compareNameToPathComponent((*iter)->getName(), path, compLen))
        {
            matchingNode = *iter;
            break;
        }
    }

    if (matchingNode)
    {
        if (path[compLen] == 0)
            return matchingNode; // Last element in path, return matching node.
        else if (matchingNode->getNodeType() == TESTNODETYPE_GROUP)
            return static_cast<const TestGroup *>(matchingNode)->findChildNode(path + compLen + 1);
        else
            return DE_NULL;
    }
    else
        return DE_NULL;
}

// TestRoot

TestRoot::TestRoot(void) : TestGroup(DE_NULL, TESTNODETYPE_ROOT, "", "")
{
}

// TestCase

TestCase *TestCase::createAsChild(TestGroup *parent, TestCaseType caseType, const char *name, const char *description)
{
    return new TestCase(parent, caseType, name, description);
}

TestCase::TestCase(TestGroup *parent, TestCaseType caseType, const char *name, const char *description)
    : TestNode(parent, TESTNODETYPE_TEST_CASE, name, description)
    , m_caseType(caseType)
{
}

TestCase::~TestCase(void)
{
}

// TestHierarchyBuilder helpers

void addChildGroupsToMap(std::map<std::string, TestGroup *> &groupMap, TestGroup *group)
{
    for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
    {
        TestNode *node = group->getChild(ndx);
        if (node->getNodeType() == TESTNODETYPE_GROUP)
        {
            TestGroup *childGroup = static_cast<TestGroup *>(node);
            std::string fullPath;
            childGroup->getFullPath(fullPath);

            groupMap.insert(std::make_pair(fullPath, childGroup));
            addChildGroupsToMap(groupMap, childGroup);
        }
    }
}

// TestHierarchyBuilder

TestHierarchyBuilder::TestHierarchyBuilder(TestRoot *root) : m_root(root)
{
    addChildGroupsToMap(m_groupMap, root);
}

TestHierarchyBuilder::~TestHierarchyBuilder(void)
{
}

TestCase *TestHierarchyBuilder::createCase(const char *path, TestCaseType caseType)
{
    // \todo [2012-09-05 pyry] This can be done with less string manipulations.
    std::vector<std::string> components;
    splitPath(path, components);
    DE_ASSERT(!components.empty());

    // Create all parents if necessary.
    TestGroup *curGroup = m_root;
    std::string curGroupPath;
    for (int ndx = 0; ndx < (int)components.size() - 1; ndx++)
    {
        if (!curGroupPath.empty())
            curGroupPath += ".";
        curGroupPath += components[ndx];

        std::map<std::string, TestGroup *>::const_iterator groupPos = m_groupMap.find(curGroupPath);
        if (groupPos == m_groupMap.end())
        {
            TestGroup *newGroup = curGroup->createGroup(components[ndx].c_str(), "" /* description */);
            m_groupMap.insert(std::make_pair(curGroupPath, newGroup));
            curGroup = newGroup;
        }
        else
            curGroup = groupPos->second;
    }

    return curGroup->createCase(caseType, components.back().c_str(), "" /* description */);
}

// TestSet helpers

static void addNodeAndParents(std::set<const TestNode *> &nodeSet, const TestNode *node)
{
    while (node != DE_NULL)
    {
        nodeSet.insert(node);
        node = node->getParent();
    }
}

static void addChildren(std::set<const TestNode *> &nodeSet, const TestGroup *group)
{
    for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
    {
        const TestNode *child = group->getChild(ndx);
        nodeSet.insert(child);

        if (child->getNodeType() == TESTNODETYPE_GROUP)
            addChildren(nodeSet, static_cast<const TestGroup *>(child));
    }
}

static void removeChildren(std::set<const TestNode *> &nodeSet, const TestGroup *group)
{
    for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
    {
        const TestNode *child = group->getChild(ndx);
        nodeSet.erase(child);

        if (child->getNodeType() == TESTNODETYPE_GROUP)
            removeChildren(nodeSet, static_cast<const TestGroup *>(child));
    }
}

static bool hasChildrenInSet(const std::set<const TestNode *> &nodeSet, const TestGroup *group)
{
    for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
    {
        if (nodeSet.find(group->getChild(ndx)) != nodeSet.end())
            return true;
    }
    return false;
}

static void removeEmptyGroups(std::set<const TestNode *> &nodeSet, const TestGroup *group)
{
    if (!hasChildrenInSet(nodeSet, group))
    {
        nodeSet.erase(group);
        if (group->getParent() != DE_NULL)
            removeEmptyGroups(nodeSet, group->getParent());
    }
}

// TestSet

void TestSet::add(const TestNode *node)
{
    if (node->getNodeType() == TESTNODETYPE_TEST_CASE)
        addCase(static_cast<const TestCase *>(node));
    else
    {
        XE_CHECK(node->getNodeType() == TESTNODETYPE_GROUP || node->getNodeType() == TESTNODETYPE_ROOT);
        addGroup(static_cast<const TestGroup *>(node));
    }
}

void TestSet::addCase(const TestCase *testCase)
{
    addNodeAndParents(m_set, testCase);
}

void TestSet::addGroup(const TestGroup *testGroup)
{
    addNodeAndParents(m_set, testGroup);
    addChildren(m_set, testGroup);
}

void TestSet::remove(const TestNode *node)
{
    if (node->getNodeType() == TESTNODETYPE_TEST_CASE)
        removeCase(static_cast<const TestCase *>(node));
    else
    {
        XE_CHECK(node->getNodeType() == TESTNODETYPE_GROUP || node->getNodeType() == TESTNODETYPE_ROOT);
        removeGroup(static_cast<const TestGroup *>(node));
    }
}

void TestSet::removeCase(const TestCase *testCase)
{
    if (m_set.find(testCase) != m_set.end())
    {
        m_set.erase(testCase);
        removeEmptyGroups(m_set, testCase->getParent());
    }
}

void TestSet::removeGroup(const TestGroup *testGroup)
{
    if (m_set.find(testGroup) != m_set.end())
    {
        m_set.erase(testGroup);
        removeChildren(m_set, testGroup);
        if (testGroup->getParent() != DE_NULL)
            removeEmptyGroups(m_set, testGroup->getParent());
    }
}

// ConstTestNodeIterator

ConstTestNodeIterator::ConstTestNodeIterator(const TestNode *root) : m_root(root)
{
}

ConstTestNodeIterator ConstTestNodeIterator::begin(const TestNode *root)
{
    ConstTestNodeIterator iter(root);
    iter.m_iterStack.push_back(GroupState(DE_NULL));
    return iter;
}

ConstTestNodeIterator ConstTestNodeIterator::end(const TestNode *root)
{
    DE_UNREF(root);
    return ConstTestNodeIterator(root);
}

ConstTestNodeIterator &ConstTestNodeIterator::operator++(void)
{
    DE_ASSERT(!m_iterStack.empty());

    const TestNode *curNode  = **this;
    TestNodeType curNodeType = curNode->getNodeType();

    if ((curNodeType == TESTNODETYPE_GROUP || curNodeType == TESTNODETYPE_ROOT) &&
        static_cast<const TestGroup *>(curNode)->getNumChildren() > 0)
    {
        m_iterStack.push_back(GroupState(static_cast<const TestGroup *>(curNode)));
    }
    else
    {
        for (;;)
        {
            const TestGroup *group = m_iterStack.back().group;
            int &childNdx          = m_iterStack.back().childNdx;
            int numChildren        = group ? group->getNumChildren() : 1;

            childNdx += 1;
            if (childNdx == numChildren)
            {
                m_iterStack.pop_back();
                if (m_iterStack.empty())
                    break;
            }
            else
                break;
        }
    }

    return *this;
}

ConstTestNodeIterator ConstTestNodeIterator::operator++(int)
{
    ConstTestNodeIterator copy(*this);
    ++(*this);
    return copy;
}

const TestNode *ConstTestNodeIterator::operator*(void) const
{
    DE_ASSERT(!m_iterStack.empty());
    if (m_iterStack.size() == 1)
    {
        DE_ASSERT(m_iterStack[0].group == DE_NULL && m_iterStack[0].childNdx == 0);
        return m_root;
    }
    else
        return m_iterStack.back().group->getChild(m_iterStack.back().childNdx);
}

bool ConstTestNodeIterator::operator!=(const ConstTestNodeIterator &other) const
{
    return m_root != other.m_root || m_iterStack != other.m_iterStack;
}

} // namespace xe
