// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/test/gtest_xml_util.h"

#include "base/base64.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/gtest_util.h"
#include "base/test/launcher/test_launcher.h"
#include "starboard/types.h"
#include "third_party/libxml/chromium/libxml_utils.h"

namespace base {

namespace {

// This is used for the xml parser to report errors. This assumes the context
// is a pointer to a std::string where the error message should be appended.
static void XmlErrorFunc(void *context, const char *message, ...) {
  va_list args;
  va_start(args, message);
  std::string* error = static_cast<std::string*>(context);
  StringAppendV(error, message, args);
  va_end(args);
}

}  // namespace

bool ProcessGTestOutput(const base::FilePath& output_file,
                        std::vector<TestResult>* results,
                        bool* crashed) {
  DCHECK(results);

  std::string xml_contents;
  if (!ReadFileToString(output_file, &xml_contents))
    return false;

  // Silence XML errors - otherwise they go to stderr.
  std::string xml_errors;
  ScopedXmlErrorFunc error_func(&xml_errors, &XmlErrorFunc);

  XmlReader xml_reader;
  if (!xml_reader.Load(xml_contents))
    return false;

  enum {
    STATE_INIT,
    STATE_TESTSUITE,
    STATE_TESTCASE,
    STATE_TEST_RESULT,
    STATE_FAILURE,
    STATE_END,
  } state = STATE_INIT;

  while (xml_reader.Read()) {
    xml_reader.SkipToElement();
    std::string node_name(xml_reader.NodeName());

    switch (state) {
      case STATE_INIT:
        if (node_name == "testsuites" && !xml_reader.IsClosingElement())
          state = STATE_TESTSUITE;
        else
          return false;
        break;
      case STATE_TESTSUITE:
        if (node_name == "testsuites" && xml_reader.IsClosingElement())
          state = STATE_END;
        else if (node_name == "testsuite" && !xml_reader.IsClosingElement())
          state = STATE_TESTCASE;
        else
          return false;
        break;
      case STATE_TESTCASE:
        if (node_name == "testsuite" && xml_reader.IsClosingElement()) {
          state = STATE_TESTSUITE;
        } else if (node_name == "x-teststart" &&
                   !xml_reader.IsClosingElement()) {
          // This is our custom extension that helps recognize which test was
          // running when the test binary crashed.
          TestResult result;

          std::string test_case_name;
          if (!xml_reader.NodeAttribute("classname", &test_case_name))
            return false;
          std::string test_name;
          if (!xml_reader.NodeAttribute("name", &test_name))
            return false;
          result.full_name = FormatFullTestName(test_case_name, test_name);

          result.elapsed_time = TimeDelta();

          // Assume the test crashed - we can correct that later.
          result.status = TestResult::TEST_CRASH;

          results->push_back(result);
        } else if (node_name == "testcase" && !xml_reader.IsClosingElement()) {
          std::string test_status;
          if (!xml_reader.NodeAttribute("status", &test_status))
            return false;

          if (test_status != "run" && test_status != "notrun")
            return false;
          if (test_status != "run")
            break;

          TestResult result;

          std::string test_case_name;
          if (!xml_reader.NodeAttribute("classname", &test_case_name))
            return false;
          std::string test_name;
          if (!xml_reader.NodeAttribute("name", &test_name))
            return false;
          result.full_name = test_case_name + "." + test_name;

          std::string test_time_str;
          if (!xml_reader.NodeAttribute("time", &test_time_str))
            return false;
          result.elapsed_time = TimeDelta::FromMicroseconds(
              static_cast<int64_t>(strtod(test_time_str.c_str(), nullptr) *
                                   Time::kMicrosecondsPerSecond));

          result.status = TestResult::TEST_SUCCESS;

          if (!results->empty() &&
              results->back().full_name == result.full_name &&
              results->back().status == TestResult::TEST_CRASH) {
            // Erase the fail-safe "crashed" result - now we know the test did
            // not crash.
            results->pop_back();
          }

          results->push_back(result);
        } else if (node_name == "failure" && !xml_reader.IsClosingElement()) {
          std::string failure_message;
          if (!xml_reader.NodeAttribute("message", &failure_message))
            return false;

          DCHECK(!results->empty());
          results->back().status = TestResult::TEST_FAILURE;

          state = STATE_FAILURE;
        } else if (node_name == "testcase" && xml_reader.IsClosingElement()) {
          // Deliberately empty.
        } else if (node_name == "x-test-result-part" &&
                   !xml_reader.IsClosingElement()) {
          std::string result_type;
          if (!xml_reader.NodeAttribute("type", &result_type))
            return false;

          std::string file_name;
          if (!xml_reader.NodeAttribute("file", &file_name))
            return false;

          std::string line_number_str;
          if (!xml_reader.NodeAttribute("line", &line_number_str))
            return false;

          int line_number;
          if (!StringToInt(line_number_str, &line_number))
            return false;

          TestResultPart::Type type;
          if (!TestResultPart::TypeFromString(result_type, &type))
            return false;

          TestResultPart test_result_part;
          test_result_part.type = type;
          test_result_part.file_name = file_name,
          test_result_part.line_number = line_number;
          DCHECK(!results->empty());
          results->back().test_result_parts.push_back(test_result_part);

          state = STATE_TEST_RESULT;
        } else {
          return false;
        }
        break;
      case STATE_TEST_RESULT:
        if (node_name == "summary" && !xml_reader.IsClosingElement()) {
          std::string summary;
          if (!xml_reader.ReadElementContent(&summary))
            return false;

          if (!Base64Decode(summary, &summary))
            return false;

          DCHECK(!results->empty());
          DCHECK(!results->back().test_result_parts.empty());
          results->back().test_result_parts.back().summary = summary;
        } else if (node_name == "summary" && xml_reader.IsClosingElement()) {
        } else if (node_name == "message" && !xml_reader.IsClosingElement()) {
          std::string message;
          if (!xml_reader.ReadElementContent(&message))
            return false;

          if (!Base64Decode(message, &message))
            return false;

          DCHECK(!results->empty());
          DCHECK(!results->back().test_result_parts.empty());
          results->back().test_result_parts.back().message = message;
        } else if (node_name == "message" && xml_reader.IsClosingElement()) {
        } else if (node_name == "x-test-result-part" &&
                   xml_reader.IsClosingElement()) {
          state = STATE_TESTCASE;
        } else {
          return false;
        }
        break;
      case STATE_FAILURE:
        if (node_name == "failure" && xml_reader.IsClosingElement())
          state = STATE_TESTCASE;
        else
          return false;
        break;
      case STATE_END:
        // If we are here and there are still XML elements, the file has wrong
        // format.
        return false;
    }
  }

  *crashed = (state != STATE_END);
  return true;
}

}  // namespace base
