// Copyright 2018 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/protocol_serializer_json.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/json/json_writer.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/update_client/updater_state.h"

namespace update_client {

using Value = base::Value;

std::string ProtocolSerializerJSON::Serialize(
    const protocol_request::Request& request) const {
  Value root_node(Value::Type::DICTIONARY);
  auto* request_node =
      root_node.SetKey("request", Value(Value::Type::DICTIONARY));
  request_node->SetKey("protocol", Value(request.protocol_version));
  request_node->SetKey("dedup", Value("cr"));
  request_node->SetKey("acceptformat", Value("crx2,crx3"));
  if (!request.additional_attributes.empty()) {
    for (const auto& attr : request.additional_attributes)
      request_node->SetKey(attr.first, Value(attr.second));
  }
  request_node->SetKey("sessionid", Value(request.session_id));
  request_node->SetKey("requestid", Value(request.request_id));
  request_node->SetKey("@updater", Value(request.updatername));
  request_node->SetKey("prodversion", Value(request.updaterversion));
  request_node->SetKey("updaterversion", Value(request.prodversion));
  request_node->SetKey("lang", Value(request.lang));
  request_node->SetKey("@os", Value(request.operating_system));
  request_node->SetKey("arch", Value(request.arch));
  request_node->SetKey("nacl_arch", Value(request.nacl_arch));
#if defined(OS_WIN)
  if (request.is_wow64)
    request_node->SetKey("wow64", Value(request.is_wow64));
#endif  // OS_WIN
  if (!request.updaterchannel.empty())
    request_node->SetKey("updaterchannel", Value(request.updaterchannel));
  if (!request.prodchannel.empty())
    request_node->SetKey("prodchannel", Value(request.prodchannel));
  if (!request.dlpref.empty())
    request_node->SetKey("dlpref", Value(request.dlpref));
  if (request.domain_joined) {
    request_node->SetKey(UpdaterState::kIsEnterpriseManaged,
                         Value(*request.domain_joined));
  }

  // HW platform information.
  auto* hw_node = request_node->SetKey("hw", Value(Value::Type::DICTIONARY));
  hw_node->SetKey("physmemory", Value(static_cast<int>(request.hw.physmemory)));

  // OS version and platform information.
  auto* os_node = request_node->SetKey("os", Value(Value::Type::DICTIONARY));
  os_node->SetKey("platform", Value(request.os.platform));
  os_node->SetKey("arch", Value(request.os.arch));
  if (!request.os.version.empty())
    os_node->SetKey("version", Value(request.os.version));
  if (!request.os.service_pack.empty())
    os_node->SetKey("sp", Value(request.os.service_pack));

#if defined(GOOGLE_CHROME_BUILD)
  if (request.updater) {
    const auto& updater = *request.updater;
    auto* updater_node =
        request_node->SetKey("updater", Value(Value::Type::DICTIONARY));
    updater_node->SetKey("name", Value(updater.name));
    updater_node->SetKey("ismachine", Value(updater.is_machine));
    updater_node->SetKey("autoupdatecheckenabled",
                         Value(updater.autoupdate_check_enabled));
    updater_node->SetKey("updatepolicy", Value(updater.update_policy));
    if (!updater.version.empty())
      updater_node->SetKey("version", Value(updater.version));
    if (updater.last_checked)
      updater_node->SetKey("lastchecked", Value(*updater.last_checked));
    if (updater.last_started)
      updater_node->SetKey("laststarted", Value(*updater.last_started));
  }
#endif

  std::vector<Value> app_nodes;
  for (const auto& app : request.apps) {
    Value app_node(Value::Type::DICTIONARY);
    app_node.SetKey("appid", Value(app.app_id));
    app_node.SetKey("version", Value(app.version));
    if (!app.brand_code.empty())
      app_node.SetKey("brand", Value(app.brand_code));
    if (!app.install_source.empty())
      app_node.SetKey("installsource", Value(app.install_source));
    if (!app.install_location.empty())
      app_node.SetKey("installedby", Value(app.install_location));
    if (!app.cohort.empty())
      app_node.SetKey("cohort", Value(app.cohort));
    if (!app.cohort_name.empty())
      app_node.SetKey("cohortname", Value(app.cohort_name));
    if (!app.cohort_hint.empty())
      app_node.SetKey("cohorthint", Value(app.cohort_hint));
    if (app.enabled)
      app_node.SetKey("enabled", Value(*app.enabled));

    if (app.disabled_reasons && !app.disabled_reasons->empty()) {
      std::vector<Value> disabled_nodes;
      for (const int disabled_reason : *app.disabled_reasons) {
        Value disabled_node(Value::Type::DICTIONARY);
        disabled_node.SetKey("reason", Value(disabled_reason));
        disabled_nodes.push_back(std::move(disabled_node));
      }
      app_node.SetKey("disabled", Value(disabled_nodes));
    }

    for (const auto& attr : app.installer_attributes)
      app_node.SetKey(attr.first, Value(attr.second));

    if (app.update_check) {
      auto* update_check_node =
          app_node.SetKey("updatecheck", Value(Value::Type::DICTIONARY));
      if (app.update_check->is_update_disabled)
        update_check_node->SetKey("updatedisabled", Value(true));
    }

    if (app.ping) {
      const auto& ping = *app.ping;
      auto* ping_node = app_node.SetKey("ping", Value(Value::Type::DICTIONARY));
      if (!ping.ping_freshness.empty())
        ping_node->SetKey("ping_freshness", Value(ping.ping_freshness));

      // Output "ad" or "a" only if the this app has been seen 'active'.
      if (ping.date_last_active) {
        ping_node->SetKey("ad", Value(*ping.date_last_active));
      } else if (ping.days_since_last_active_ping) {
        ping_node->SetKey("a", Value(*ping.days_since_last_active_ping));
      }

      // Output "rd" if valid or "r" as a last resort roll call metric.
      if (ping.date_last_roll_call)
        ping_node->SetKey("rd", Value(*ping.date_last_roll_call));
      else
        ping_node->SetKey("r", Value(ping.days_since_last_roll_call));
    }

    if (!app.fingerprint.empty()) {
      std::vector<Value> package_nodes;
      Value package(Value::Type::DICTIONARY);
      package.SetKey("fp", Value(app.fingerprint));
      package_nodes.push_back(std::move(package));
      auto* packages_node =
          app_node.SetKey("packages", Value(Value::Type::DICTIONARY));
      packages_node->SetKey("package", Value(package_nodes));
    }

    if (app.events) {
      std::vector<Value> event_nodes;
      for (const auto& event : *app.events) {
        DCHECK(event.is_dict());
        DCHECK(!event.DictEmpty());
        event_nodes.push_back(event.Clone());
      }
      app_node.SetKey("event", Value(event_nodes));
    }

    app_nodes.push_back(std::move(app_node));
  }

  if (!app_nodes.empty())
    request_node->SetKey("app", Value(std::move(app_nodes)));

  std::string msg;
  return base::JSONWriter::WriteWithOptions(
             root_node, base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION,
             &msg)
             ? msg
             : std::string();
}

}  // namespace update_client
