// 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 <stdint.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 "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
