/*-------------------------------------------------------------------------
 * 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 list parser.
 *//*--------------------------------------------------------------------*/

#include "xeTestCaseListParser.hpp"
#include "deString.h"

using std::string;
using std::vector;

namespace xe
{

static TestCaseType getTestCaseType(const char *caseType)
{
    // \todo [2012-06-11 pyry] Use hashes for speedup.
    static const struct
    {
        const char *name;
        TestCaseType caseType;
    } s_caseTypeMap[] = {{"SelfValidate", TESTCASETYPE_SELF_VALIDATE},
                         {"Capability", TESTCASETYPE_CAPABILITY},
                         {"Accuracy", TESTCASETYPE_ACCURACY},
                         {"Performance", TESTCASETYPE_PERFORMANCE}};

    for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_caseTypeMap); ndx++)
    {
        if (deStringEqual(caseType, s_caseTypeMap[ndx].name))
            return s_caseTypeMap[ndx].caseType;
    }

    XE_FAIL((string("Unknown test case type '") + caseType + "'").c_str());
}

TestCaseListParser::TestCaseListParser(void) : m_root(DE_NULL)
{
}

TestCaseListParser::~TestCaseListParser(void)
{
}

void TestCaseListParser::clear(void)
{
    m_xmlParser.clear();
    m_nodeStack.clear();
    m_root = DE_NULL;
}

void TestCaseListParser::init(TestGroup *rootGroup)
{
    clear();
    m_root = rootGroup;
}

void TestCaseListParser::parse(const uint8_t *bytes, int numBytes)
{
    DE_ASSERT(m_root);
    m_xmlParser.feed(bytes, numBytes);

    for (;;)
    {
        xml::Element element = m_xmlParser.getElement();

        if (element == xml::ELEMENT_INCOMPLETE || element == xml::ELEMENT_END_OF_STRING)
            break;

        if (element == xml::ELEMENT_START || element == xml::ELEMENT_END)
        {
            bool isStart         = element == xml::ELEMENT_START;
            const char *elemName = m_xmlParser.getElementName();

            if (deStringEqual(elemName, "TestCase"))
            {
                if (isStart)
                {
                    XE_CHECK_MSG(!m_nodeStack.empty(), "<TestCase> outside of <TestCaseList>");

                    TestNode *parent = m_nodeStack.back();
                    const char *name = m_xmlParser.hasAttribute("Name") ? m_xmlParser.getAttribute("Name") : DE_NULL;
                    const char *description =
                        m_xmlParser.hasAttribute("Description") ? m_xmlParser.getAttribute("Description") : DE_NULL;
                    const char *caseType =
                        m_xmlParser.hasAttribute("CaseType") ? m_xmlParser.getAttribute("CaseType") : DE_NULL;

                    XE_CHECK_MSG(name && description && caseType, "Missing attribute in <TestCase>");
                    XE_CHECK_MSG(parent->getNodeType() == TESTNODETYPE_GROUP,
                                 "Only TestGroups are allowed to have child nodes");

                    bool isGroup = deStringEqual(caseType, "TestGroup") == true;
                    TestNode *node =
                        isGroup ?
                            static_cast<TestNode *>(static_cast<TestGroup *>(parent)->createGroup(name, description)) :
                            static_cast<TestNode *>(static_cast<TestGroup *>(parent)->createCase(
                                getTestCaseType(caseType), name, description));

                    m_nodeStack.push_back(node);
                }
                else
                {
                    XE_CHECK_MSG(m_nodeStack.size() >= 2, "Unexpected </TestCase>");
                    m_nodeStack.pop_back();
                }
            }
            else if (deStringEqual(elemName, "TestCaseList"))
            {
                if (isStart)
                {
                    XE_CHECK_MSG(m_nodeStack.empty(), "Unexpected <TestCaseList>");
                    m_nodeStack.push_back(m_root);
                }
                else
                {
                    XE_CHECK_MSG(m_nodeStack.size() == 1, "Unexpected </TestCaseList>");
                    m_nodeStack.pop_back();
                }
            }
            else
                XE_FAIL((string("Unexpected <") + elemName + ">").c_str());
        }
        else if (element != xml::ELEMENT_DATA)
            DE_ASSERT(false); // \note Data elements are just ignored, they should be whitespace anyway.

        m_xmlParser.advance();
    }
}

} // namespace xe
