// Copyright (c) 2012 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 "chrome/common/extensions/update_manifest.h"

#include <algorithm>

#include "base/memory/scoped_ptr.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"

static const char* kExpectedGupdateProtocol = "2.0";
static const char* kExpectedGupdateXmlns =
    "http://www.google.com/update2/response";

UpdateManifest::Result::Result()
    : size(0),
      diff_size(0) {}

UpdateManifest::Result::~Result() {}

UpdateManifest::Results::Results() : daystart_elapsed_seconds(kNoDaystart) {}

UpdateManifest::Results::~Results() {}

UpdateManifest::UpdateManifest() {
}

UpdateManifest::~UpdateManifest() {}

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

  if (errors_.length() > 0) {
    // TODO(asargent) make a platform abstracted newline?
    errors_ += "\r\n";
  }
  base::StringAppendV(&errors_, details, args);
  va_end(args);
}

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

// Returns child nodes of |root| with name |name| in namespace |xml_namespace|.
static std::vector<xmlNode*> GetChildren(xmlNode* root, xmlNs* xml_namespace,
                                         const char* name) {
  std::vector<xmlNode*> result;
  for (xmlNode* child = root->children; child != NULL; child = child->next) {
    if (!TagNameEquals(child, name, xml_namespace)) {
      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();
}

// 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_;
};

// Returns a pointer to the xmlNs on |node| with the |expected_href|, or
// NULL if there isn't one with that href.
static xmlNs* GetNamespace(xmlNode* node, const char* expected_href) {
  const xmlChar* href = reinterpret_cast<const xmlChar*>(expected_href);
  for (xmlNs* ns = node->ns; ns != NULL; ns = ns->next) {
    if (ns->href && !xmlStrcmp(ns->href, href)) {
      return ns;
    }
  }
  return NULL;
}


// Helper function that reads in values for a single <app> tag. It returns a
// boolean indicating success or failure. On failure, it writes a error message
// into |error_detail|.
static bool ParseSingleAppTag(xmlNode* app_node, xmlNs* xml_namespace,
                              UpdateManifest::Result* result,
                              std::string *error_detail) {
  // Read the extension id.
  result->extension_id = GetAttribute(app_node, "appid");
  if (result->extension_id.length() == 0) {
    *error_detail = "Missing appid on app node";
    return false;
  }

  // Get the updatecheck node.
  std::vector<xmlNode*> updates = GetChildren(app_node, xml_namespace,
                                              "updatecheck");
  if (updates.size() > 1) {
    *error_detail = "Too many updatecheck tags on app (expecting only 1).";
    return false;
  }
  if (updates.empty()) {
    *error_detail = "Missing updatecheck on app.";
    return false;
  }
  xmlNode *updatecheck = updates[0];

  if (GetAttribute(updatecheck, "status") == "noupdate") {
    return true;
  }

  // Find the url to the crx file.
  result->crx_url = GURL(GetAttribute(updatecheck, "codebase"));
  if (!result->crx_url.is_valid()) {
    *error_detail = "Invalid codebase url: '";
    *error_detail += result->crx_url.possibly_invalid_spec();
    *error_detail += "'.";
    return false;
  }

  // Get the version.
  result->version = GetAttribute(updatecheck, "version");
  if (result->version.length() == 0) {
    *error_detail = "Missing version for updatecheck.";
    return false;
  }
  Version version(result->version);
  if (!version.IsValid()) {
    *error_detail = "Invalid version: '";
    *error_detail += result->version;
    *error_detail += "'.";
    return false;
  }

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

  // package_hash is optional. It is only required for blacklist. It is a
  // sha256 hash of the package in hex format.
  result->package_hash = GetAttribute(updatecheck, "hash");

  int size = 0;
  if (base::StringToInt(GetAttribute(updatecheck, "size"), &size)) {
    result->size = size;
  }

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

  // Differential update information is optional.
  result->diff_crx_url = GURL(GetAttribute(updatecheck, "codebasediff"));
  result->diff_package_hash = GetAttribute(updatecheck, "hashdiff");
  int sizediff = 0;
  if (base::StringToInt(GetAttribute(updatecheck, "sizediff"), &sizediff)) {
    result->diff_size = sizediff;
  }

  return true;
}


bool UpdateManifest::Parse(const std::string& manifest_xml) {
  results_.list.resize(0);
  results_.daystart_elapsed_seconds = kNoDaystart;
  errors_ = "";

  if (manifest_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*>(manifest_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;
  }

  // Look for the required namespace declaration.
  xmlNs* gupdate_ns = GetNamespace(root, kExpectedGupdateXmlns);
  if (!gupdate_ns) {
    ParseError("Missing or incorrect xmlns on gupdate tag");
    return false;
  }

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

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

  // Parse the first <daystart> if it's present.
  std::vector<xmlNode*> daystarts = GetChildren(root, gupdate_ns, "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;
    }
  }

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

  return true;
}
