// Copyright 2014 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 "components/update_client/update_response.h"

#include <stddef.h>

#include <algorithm>
#include <memory>

#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/version.h"
#include "libxml/tree.h"
#include "third_party/libxml/chromium/libxml_utils.h"

namespace update_client {

static const char* kExpectedResponseProtocol = "3.0";
const char UpdateResponse::Result::kCohort[] = "cohort";
const char UpdateResponse::Result::kCohortHint[] = "cohorthint";
const char UpdateResponse::Result::kCohortName[] = "cohortname";

UpdateResponse::UpdateResponse() {
}
UpdateResponse::~UpdateResponse() {
}

UpdateResponse::Results::Results() : daystart_elapsed_seconds(kNoDaystart) {
}
UpdateResponse::Results::Results(const Results& other) = default;
UpdateResponse::Results::~Results() {
}

UpdateResponse::Result::Result() {}
UpdateResponse::Result::Result(const Result& other) = default;
UpdateResponse::Result::~Result() {
}

UpdateResponse::Result::Manifest::Manifest() {
}
UpdateResponse::Result::Manifest::Manifest(const Manifest& other) = default;
UpdateResponse::Result::Manifest::~Manifest() {
}

UpdateResponse::Result::Manifest::Package::Package() : size(0), sizediff(0) {
}
UpdateResponse::Result::Manifest::Package::Package(const Package& other) =
    default;
UpdateResponse::Result::Manifest::Package::~Package() {
}

void UpdateResponse::ParseError(const char* details, ...) {
  va_list args;
  va_start(args, details);

  if (!errors_.empty()) {
    errors_ += "\r\n";
  }

  base::StringAppendV(&errors_, details, args);
  va_end(args);
}

// Checks whether a given node's name matches |expected_name|.
static bool TagNameEquals(const xmlNode* node, const char* expected_name) {
  return 0 == strcmp(expected_name, reinterpret_cast<const char*>(node->name));
}

// Returns child nodes of |root| with name |name|.
static std::vector<xmlNode*> GetChildren(xmlNode* root, const char* name) {
  std::vector<xmlNode*> result;
  for (xmlNode* child = root->children; child != NULL; child = child->next) {
    if (!TagNameEquals(child, name)) {
      continue;
    }
    result.push_back(child);
  }
  return result;
}

// Returns the value of a named attribute, or the empty string.
static std::string GetAttribute(xmlNode* node, const char* attribute_name) {
  const xmlChar* name = reinterpret_cast<const xmlChar*>(attribute_name);
  for (xmlAttr* attr = node->properties; attr != NULL; attr = attr->next) {
    if (!xmlStrcmp(attr->name, name) && attr->children &&
        attr->children->content) {
      return std::string(
          reinterpret_cast<const char*>(attr->children->content));
    }
  }
  return std::string();
}

// Returns the value of a named attribute, or nullptr .
static std::unique_ptr<std::string> GetAttributePtr(
    xmlNode* node,
    const char* attribute_name) {
  const xmlChar* name = reinterpret_cast<const xmlChar*>(attribute_name);
  for (xmlAttr* attr = node->properties; attr != NULL; attr = attr->next) {
    if (!xmlStrcmp(attr->name, name) && attr->children &&
        attr->children->content) {
      return base::MakeUnique<std::string>(
          reinterpret_cast<const char*>(attr->children->content));
    }
  }
  return nullptr;
}

// 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);
  base::StringAppendV(error, message, args);
  va_end(args);
}

// Utility class for cleaning up the xml document when leaving a scope.
class ScopedXmlDocument {
 public:
  explicit ScopedXmlDocument(xmlDocPtr document) : document_(document) {}
  ~ScopedXmlDocument() {
    if (document_)
      xmlFreeDoc(document_);
  }

  xmlDocPtr get() { return document_; }

 private:
  xmlDocPtr document_;
};

// Parses the <package> tag.
bool ParsePackageTag(xmlNode* package,
                     UpdateResponse::Result* result,
                     std::string* error) {
  UpdateResponse::Result::Manifest::Package p;
  p.name = GetAttribute(package, "name");
  if (p.name.empty()) {
    *error = "Missing name for package.";
    return false;
  }

  p.namediff = GetAttribute(package, "namediff");

  // package_fingerprint is optional. It identifies the package, preferably
  // with a modified sha256 hash of the package in hex format.
  p.fingerprint = GetAttribute(package, "fp");

  p.hash_sha256 = GetAttribute(package, "hash_sha256");
  int size = 0;
  if (base::StringToInt(GetAttribute(package, "size"), &size)) {
    p.size = size;
  }

  p.hashdiff_sha256 = GetAttribute(package, "hashdiff_sha256");
  int sizediff = 0;
  if (base::StringToInt(GetAttribute(package, "sizediff"), &sizediff)) {
    p.sizediff = sizediff;
  }

  result->manifest.packages.push_back(p);

  return true;
}

// Parses the <manifest> tag.
bool ParseManifestTag(xmlNode* manifest,
                      UpdateResponse::Result* result,
                      std::string* error) {
  // Get the version.
  result->manifest.version = GetAttribute(manifest, "version");
  if (result->manifest.version.empty()) {
    *error = "Missing version for manifest.";
    return false;
  }
  base::Version version(result->manifest.version);
  if (!version.IsValid()) {
    *error = "Invalid version: '";
    *error += result->manifest.version;
    *error += "'.";
    return false;
  }

  // Get the minimum browser version (not required).
  result->manifest.browser_min_version =
      GetAttribute(manifest, "prodversionmin");
  if (result->manifest.browser_min_version.length()) {
    base::Version browser_min_version(result->manifest.browser_min_version);
    if (!browser_min_version.IsValid()) {
      *error = "Invalid prodversionmin: '";
      *error += result->manifest.browser_min_version;
      *error += "'.";
      return false;
    }
  }

  // Get the <packages> node.
  std::vector<xmlNode*> packages = GetChildren(manifest, "packages");
  if (packages.empty()) {
    *error = "Missing packages tag on manifest.";
    return false;
  }

  // Parse each of the <package> tags.
  std::vector<xmlNode*> package = GetChildren(packages[0], "package");
  for (size_t i = 0; i != package.size(); ++i) {
    if (!ParsePackageTag(package[i], result, error))
      return false;
  }

  return true;
}

// Parses the <urls> tag and its children in the <updatecheck>.
bool ParseUrlsTag(xmlNode* urls,
                  UpdateResponse::Result* result,
                  std::string* error) {
  // Get the url nodes.
  std::vector<xmlNode*> url = GetChildren(urls, "url");
  if (url.empty()) {
    *error = "Missing url tags on urls.";
    return false;
  }

  // Get the list of urls for full and optionally, for diff updates.
  // There can only be either a codebase or a codebasediff attribute in a tag.
  for (size_t i = 0; i != url.size(); ++i) {
    // Find the url to the crx file.
    const GURL crx_url(GetAttribute(url[i], "codebase"));
    if (crx_url.is_valid()) {
      result->crx_urls.push_back(crx_url);
      continue;
    }
    const GURL crx_diffurl(GetAttribute(url[i], "codebasediff"));
    if (crx_diffurl.is_valid()) {
      result->crx_diffurls.push_back(crx_diffurl);
      continue;
    }
  }

  // Expect at least one url for full update.
  if (result->crx_urls.empty()) {
    *error = "Missing valid url for full update.";
    return false;
  }

  return true;
}

// Parses the <updatecheck> tag.
bool ParseUpdateCheckTag(xmlNode* updatecheck,
                         UpdateResponse::Result* result,
                         std::string* error) {
  if (GetAttribute(updatecheck, "status") == "noupdate") {
    return true;
  }

  // Get the <urls> tag.
  std::vector<xmlNode*> urls = GetChildren(updatecheck, "urls");
  if (urls.empty()) {
    *error = "Missing urls on updatecheck.";
    return false;
  }

  if (!ParseUrlsTag(urls[0], result, error)) {
    return false;
  }

  std::vector<xmlNode*> manifests = GetChildren(updatecheck, "manifest");
  if (manifests.empty()) {
    *error = "Missing manifest on updatecheck.";
    return false;
  }

  return ParseManifestTag(manifests[0], result, error);
}

// Parses a single <app> tag.
bool ParseAppTag(xmlNode* app,
                 UpdateResponse::Result* result,
                 std::string* error) {
  // Read cohort information.
  auto cohort = GetAttributePtr(app, "cohort");
  static const char* attrs[] = {UpdateResponse::Result::kCohort,
                                UpdateResponse::Result::kCohortHint,
                                UpdateResponse::Result::kCohortName};
  for (const auto& attr : attrs) {
    auto value = GetAttributePtr(app, attr);
    if (value)
      result->cohort_attrs.insert({attr, *value});
  }

  // Read the crx id.
  result->extension_id = GetAttribute(app, "appid");
  if (result->extension_id.empty()) {
    *error = "Missing appid on app node";
    return false;
  }

  // Get the <updatecheck> tag.
  std::vector<xmlNode*> updates = GetChildren(app, "updatecheck");
  if (updates.empty()) {
    *error = "Missing updatecheck on app.";
    return false;
  }

  return ParseUpdateCheckTag(updates[0], result, error);
}

bool UpdateResponse::Parse(const std::string& response_xml) {
  results_.daystart_elapsed_seconds = kNoDaystart;
  results_.daystart_elapsed_days = kNoDaystart;
  results_.list.clear();
  errors_.clear();

  if (response_xml.length() < 1) {
    ParseError("Empty xml");
    return false;
  }

  std::string xml_errors;
  ScopedXmlErrorFunc error_func(&xml_errors, &XmlErrorFunc);

  // Start up the xml parser with the manifest_xml contents.
  ScopedXmlDocument document(
      xmlParseDoc(reinterpret_cast<const xmlChar*>(response_xml.c_str())));
  if (!document.get()) {
    ParseError("%s", xml_errors.c_str());
    return false;
  }

  xmlNode* root = xmlDocGetRootElement(document.get());
  if (!root) {
    ParseError("Missing root node");
    return false;
  }

  if (!TagNameEquals(root, "response")) {
    ParseError("Missing response tag");
    return false;
  }

  // Check for the response "protocol" attribute.
  if (GetAttribute(root, "protocol") != kExpectedResponseProtocol) {
    ParseError(
        "Missing/incorrect protocol on response tag "
        "(expected '%s')",
        kExpectedResponseProtocol);
    return false;
  }

  // Parse the first <daystart> if it is present.
  std::vector<xmlNode*> daystarts = GetChildren(root, "daystart");
  if (!daystarts.empty()) {
    xmlNode* first = daystarts[0];
    std::string elapsed_seconds = GetAttribute(first, "elapsed_seconds");
    int parsed_elapsed = kNoDaystart;
    if (base::StringToInt(elapsed_seconds, &parsed_elapsed)) {
      results_.daystart_elapsed_seconds = parsed_elapsed;
    }
    std::string elapsed_days = GetAttribute(first, "elapsed_days");
    parsed_elapsed = kNoDaystart;
    if (base::StringToInt(elapsed_days, &parsed_elapsed)) {
      results_.daystart_elapsed_days = parsed_elapsed;
    }
  }

  // Parse each of the <app> tags.
  std::vector<xmlNode*> apps = GetChildren(root, "app");
  for (size_t i = 0; i != apps.size(); ++i) {
    Result result;
    std::string error;
    if (ParseAppTag(apps[i], &result, &error)) {
      results_.list.push_back(result);
    } else {
      ParseError("%s", error.c_str());
    }
  }

  return true;
}

}  // namespace update_client
