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

// This is a sample daemon that "handles" Buffet commands.
// It just prints the information about the command received to stdout and
// marks the command as processed.

#include <string>
#include <sysexits.h>

#include <base/bind.h>
#include <base/command_line.h>
#include <base/format_macros.h>
#include <base/json/json_writer.h>
#include <base/values.h>
#include <chromeos/daemons/dbus_daemon.h>
#include <chromeos/map_utils.h>
#include <chromeos/strings/string_utils.h>
#include <chromeos/syslog_logging.h>

#include "buffet/dbus-proxies.h"

namespace {

std::unique_ptr<base::DictionaryValue> DictionaryToJson(
    const chromeos::VariantDictionary& dictionary);

std::unique_ptr<base::Value> AnyToJson(const chromeos::Any& value) {
  if (value.IsTypeCompatible<chromeos::VariantDictionary>())
    return DictionaryToJson(value.Get<chromeos::VariantDictionary>());

  if (value.IsTypeCompatible<std::string>()) {
    return std::unique_ptr<base::Value>{
        new base::StringValue(value.Get<std::string>())};
  }

  if (value.IsTypeCompatible<double>()) {
    return std::unique_ptr<base::Value>{
        new base::FundamentalValue(value.Get<double>())};
  }

  if (value.IsTypeCompatible<bool>()) {
    return std::unique_ptr<base::Value>{
        new base::FundamentalValue(value.Get<bool>())};
  }

  if (value.IsTypeCompatible<int>()) {
    return std::unique_ptr<base::Value>{
        new base::FundamentalValue(value.Get<int>())};
  }

  LOG(FATAL) << "Unsupported type:" << value.GetType().name();
  return {};
}

std::unique_ptr<base::DictionaryValue> DictionaryToJson(
    const chromeos::VariantDictionary& dictionary) {
  std::unique_ptr<base::DictionaryValue> result{new base::DictionaryValue};
  for (const auto& it : dictionary)
    result->Set(it.first, AnyToJson(it.second).release());
  return result;
}

std::string DictionaryToString(const chromeos::VariantDictionary& dictionary) {
  std::unique_ptr<base::DictionaryValue> json{DictionaryToJson(dictionary)};
  std::string str;
  base::JSONWriter::Write(*json, &str);
  return str;
}

}  // anonymous namespace

class Daemon final : public chromeos::DBusDaemon {
 public:
  Daemon() = default;

 protected:
  int OnInit() override;
  void OnShutdown(int* return_code) override;

 private:
  std::unique_ptr<com::android::Weave::ObjectManagerProxy> object_manager_;

  void OnBuffetCommand(com::android::Weave::CommandProxy* command);
  void OnBuffetCommandRemoved(const dbus::ObjectPath& object_path);
  void OnPropertyChange(com::android::Weave::CommandProxy* command,
                        const std::string& property_name);
  void OnCommandProgress(com::android::Weave::CommandProxy* command,
                         int progress);

  DISALLOW_COPY_AND_ASSIGN(Daemon);
};

int Daemon::OnInit() {
  int return_code = chromeos::DBusDaemon::OnInit();
  if (return_code != EX_OK)
    return return_code;

  object_manager_.reset(new com::android::Weave::ObjectManagerProxy{bus_});
  object_manager_->SetCommandAddedCallback(
      base::Bind(&Daemon::OnBuffetCommand, base::Unretained(this)));
  object_manager_->SetCommandRemovedCallback(
      base::Bind(&Daemon::OnBuffetCommandRemoved, base::Unretained(this)));

  printf("Waiting for commands...\n");
  return EX_OK;
}

void Daemon::OnShutdown(int* return_code) {
  printf("Shutting down...\n");
}

void Daemon::OnPropertyChange(com::android::Weave::CommandProxy* command,
                              const std::string& property_name) {
  printf("Notification: property '%s' on command '%s' changed.\n",
         property_name.c_str(), command->id().c_str());
  printf("  Current command status: '%s'\n", command->status().c_str());
  std::string progress = DictionaryToString(command->progress());
  printf("  Current command progress: %s\n", progress.c_str());
  std::string results = DictionaryToString(command->results());
  printf("  Current command results: %s\n", results.c_str());
}

void Daemon::OnBuffetCommand(com::android::Weave::CommandProxy* command) {
  // "Handle" only commands that belong to this daemon's category.
  if (command->status() == "done")
    return;

  command->SetPropertyChangedCallback(base::Bind(&Daemon::OnPropertyChange,
                                                 base::Unretained(this)));
  printf("++++++++++++++++++++++++++++++++++++++++++++++++\n");
  printf("Command received: %s\n", command->name().c_str());
  printf("DBus Object Path: %s\n", command->GetObjectPath().value().c_str());
  printf("              ID: %s\n", command->id().c_str());
  printf("          status: %s\n", command->status().c_str());
  printf("          origin: %s\n", command->origin().c_str());
  std::string param_names = DictionaryToString(command->parameters());
  printf(" parameters: %s\n", param_names.c_str());
  OnCommandProgress(command, 0);
}

void Daemon::OnCommandProgress(com::android::Weave::CommandProxy* command,
                               int progress) {
  printf("Updating command '%s' progress to %d%%\n", command->id().c_str(),
         progress);
  auto new_progress = command->progress();
  new_progress["progress"] = progress;
  command->SetProgress(new_progress, nullptr);

  if (progress >= 100) {
    command->Done(nullptr);
  } else {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE, base::Bind(&Daemon::OnCommandProgress,
                              base::Unretained(this), command, progress + 10),
        base::TimeDelta::FromSeconds(1));
  }
}

void Daemon::OnBuffetCommandRemoved(const dbus::ObjectPath& object_path) {
  printf("------------------------------------------------\n");
  printf("Command removed\n");
  printf("DBus Object Path: %s\n", object_path.value().c_str());
}

int main(int argc, char* argv[]) {
  base::CommandLine::Init(argc, argv);
  chromeos::InitLog(chromeos::kLogToSyslog |
                    chromeos::kLogToStderr |
                    chromeos::kLogHeader);
  Daemon daemon;
  return daemon.Run();
}
