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

#include <iostream>  // NOLINT(readability/streams)
#include <memory>
#include <string>
#include <sysexits.h>

#include <base/command_line.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include <base/values.h>
#include <chromeos/any.h>
#include <chromeos/data_encoding.h>
#include <chromeos/dbus/data_serialization.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>
#include <dbus/object_manager.h>
#include <dbus/values_util.h>

#include "buffet/libbuffet/dbus_constants.h"

using namespace buffet::dbus_constants;  // NOLINT(build/namespaces)

namespace {
static const int default_timeout_ms = 1000;

void usage() {
  std::cerr << "Possible commands:" << std::endl;
  std::cerr << "  " << kManagerTestMethod << " <message>" << std::endl;
  std::cerr << "  " << kManagerCheckDeviceRegistered << std::endl;
  std::cerr << "  " << kManagerGetDeviceInfo << std::endl;
  std::cerr << "  " << kManagerStartRegisterDevice
                    << " param1 = val1&param2 = val2..." << std::endl;
  std::cerr << "  " << kManagerFinishRegisterDevice
                    << " device_id" << std::endl;
  std::cerr << "  " << kManagerAddCommand
                    << " '{\"name\":\"command_name\",\"parameters\":{}}'"
                    << std::endl;
  std::cerr << "  " << kManagerUpdateStateMethod << std::endl;
  std::cerr << "  " << dbus::kObjectManagerGetManagedObjects << std::endl;
}

class BuffetHelperProxy {
 public:
  int Init() {
    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    bus_ = new dbus::Bus(options);
    manager_proxy_ = bus_->GetObjectProxy(
        kServiceName,
        dbus::ObjectPath(kManagerServicePath));
    root_proxy_ = bus_->GetObjectProxy(
        kServiceName,
        dbus::ObjectPath(kRootServicePath));
    return EX_OK;
  }

  int CallTestMethod(const CommandLine::StringVector& args) {
    std::string message;
    if (!args.empty())
      message = args.front();

    dbus::MethodCall method_call(kManagerInterface, kManagerTestMethod);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(message);
    scoped_ptr<dbus::Response> response(
        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
    if (!response) {
      std::cout << "Failed to receive a response." << std::endl;
      return EX_UNAVAILABLE;
    }
    dbus::MessageReader reader(response.get());
    std::string response_message;
    if (!reader.PopString(&response_message)) {
      std::cout << "No valid response." << std::endl;
      return EX_SOFTWARE;
    }
    std::cout << "Received a response: " << response_message << std::endl;
    return EX_OK;
  }

  int CallManagerCheckDeviceRegistered(const CommandLine::StringVector& args) {
    if (!args.empty()) {
      std::cerr << "Invalid number of arguments for "
                << "Manager." << kManagerCheckDeviceRegistered << std::endl;
      usage();
      return EX_USAGE;
    }
    dbus::MethodCall method_call(
        kManagerInterface, kManagerCheckDeviceRegistered);

    scoped_ptr<dbus::Response> response(
        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
    if (!response) {
      std::cout << "Failed to receive a response." << std::endl;
      return EX_UNAVAILABLE;
    }

    dbus::MessageReader reader(response.get());
    std::string device_id;
    if (!reader.PopString(&device_id)) {
      std::cout << "No device ID in response." << std::endl;
      return EX_SOFTWARE;
    }

    std::cout << "Device ID: "
              << (device_id.empty() ? std::string("<unregistered>") : device_id)
              << std::endl;
    return EX_OK;
  }

  int CallManagerGetDeviceInfo(const CommandLine::StringVector& args) {
    if (!args.empty()) {
      std::cerr << "Invalid number of arguments for "
                << "Manager." << kManagerGetDeviceInfo << std::endl;
      usage();
      return EX_USAGE;
    }
    dbus::MethodCall method_call(
        kManagerInterface, kManagerGetDeviceInfo);

    scoped_ptr<dbus::Response> response(
        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
    if (!response) {
      std::cout << "Failed to receive a response." << std::endl;
      return EX_UNAVAILABLE;
    }

    dbus::MessageReader reader(response.get());
    std::string device_info;
    if (!reader.PopString(&device_info)) {
      std::cout << "No device info in response." << std::endl;
      return EX_SOFTWARE;
    }

    std::cout << "Device Info: "
      << (device_info.empty() ? std::string("<unregistered>") : device_info)
      << std::endl;
    return EX_OK;
  }

  int CallManagerStartRegisterDevice(const CommandLine::StringVector& args) {
    if (args.size() > 1) {
      std::cerr << "Invalid number of arguments for "
                << "Manager." << kManagerStartRegisterDevice << std::endl;
      usage();
      return EX_USAGE;
    }
    chromeos::dbus_utils::Dictionary params;

    if (!args.empty()) {
      auto key_values = chromeos::data_encoding::WebParamsDecode(args.front());
      for (const auto& pair : key_values) {
        params.insert(std::make_pair(pair.first, chromeos::Any(pair.second)));
      }
    }

    dbus::MethodCall method_call(
        kManagerInterface, kManagerStartRegisterDevice);
    dbus::MessageWriter writer(&method_call);
    CHECK(chromeos::dbus_utils::AppendValueToWriter(&writer, params))
        << "Failed to send the parameters over D-Bus";

    static const int timeout_ms = 3000;
    scoped_ptr<dbus::Response> response(
        manager_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
    if (!response) {
      std::cout << "Failed to receive a response." << std::endl;
      return EX_UNAVAILABLE;
    }

    dbus::MessageReader reader(response.get());
    std::string info;
    if (!reader.PopString(&info)) {
      std::cout << "No valid response." << std::endl;
      return EX_SOFTWARE;
    }

    std::cout << "Registration started: " << info << std::endl;
    return EX_OK;
  }

  int CallManagerFinishRegisterDevice(const CommandLine::StringVector& args) {
    if (args.size() > 1) {
      std::cerr << "Invalid number of arguments for "
                << "Manager." << kManagerFinishRegisterDevice << std::endl;
      usage();
      return EX_USAGE;
    }
    dbus::MethodCall method_call(
        kManagerInterface, kManagerFinishRegisterDevice);
    dbus::MessageWriter writer(&method_call);
    std::string user_auth_code;
    if (!args.empty()) { user_auth_code = args.front(); }
    writer.AppendString(user_auth_code);
    static const int timeout_ms = 10000;
    scoped_ptr<dbus::Response> response(
        manager_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
    if (!response) {
      std::cout << "Failed to receive a response." << std::endl;
      return EX_UNAVAILABLE;
    }

    dbus::MessageReader reader(response.get());
    std::string device_id;
    if (!reader.PopString(&device_id)) {
      std::cout << "No device ID in response." << std::endl;
      return EX_SOFTWARE;
    }

    std::cout << "Device ID is "
              << (device_id.empty() ? std::string("<unregistered>") : device_id)
              << std::endl;
    return EX_OK;
  }

  int CallManagerUpdateState(const CommandLine::StringVector& args) {
    if (args.size() != 1) {
      std::cerr << "Invalid number of arguments for "
                << "Manager." << kManagerUpdateStateMethod << std::endl;
      usage();
      return EX_USAGE;
    }
    dbus::MethodCall method_call(
        kManagerInterface, kManagerUpdateStateMethod);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(args.front());
    scoped_ptr<dbus::Response> response(
        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
    if (!response) {
      std::cout << "Failed to receive a response." << std::endl;
      return EX_UNAVAILABLE;
    }
    return EX_OK;
  }

  int CallManagerAddCommand(const CommandLine::StringVector& args) {
    if (args.size() != 1) {
      std::cerr << "Invalid number of arguments for "
                << "Manager." << kManagerAddCommand << std::endl;
      usage();
      return EX_USAGE;
    }
    dbus::MethodCall method_call(
        kManagerInterface, kManagerAddCommand);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(args.front());
    scoped_ptr<dbus::Response> response(
        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
    if (!response) {
      std::cout << "Failed to receive a response." << std::endl;
      return EX_UNAVAILABLE;
    }
    return EX_OK;
  }

  int CallRootGetManagedObjects(const CommandLine::StringVector& args) {
    if (!args.empty()) {
      std::cerr << "Invalid number of arguments for "
                << dbus::kObjectManagerGetManagedObjects << std::endl;
      usage();
      return EX_USAGE;
    }
    dbus::MethodCall method_call(
        dbus::kObjectManagerInterface, dbus::kObjectManagerGetManagedObjects);
    scoped_ptr<dbus::Response> response(
        root_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
    if (!response) {
      std::cout << "Failed to receive a response." << std::endl;
      return EX_UNAVAILABLE;
    }
    std::cout << response->ToString() << std::endl;
    return EX_OK;
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  dbus::ObjectProxy* manager_proxy_{nullptr};
  dbus::ObjectProxy* root_proxy_{nullptr};
};

}  // namespace

int main(int argc, char** argv) {
  CommandLine::Init(argc, argv);
  CommandLine* cl = CommandLine::ForCurrentProcess();
  CommandLine::StringVector args = cl->GetArgs();
  if (args.empty()) {
    usage();
    return EX_USAGE;
  }

  // Pop the command off of the args list.
  std::string command = args.front();
  args.erase(args.begin());
  int err = EX_USAGE;
  BuffetHelperProxy helper;
  err = helper.Init();
  if (err) {
    std::cerr << "Error initializing proxies." << std::endl;
    return err;
  }

  if (command.compare(kManagerTestMethod) == 0) {
    err = helper.CallTestMethod(args);
  } else if (command.compare(kManagerCheckDeviceRegistered) == 0 ||
             command.compare("cr") == 0) {
    err = helper.CallManagerCheckDeviceRegistered(args);
  } else if (command.compare(kManagerGetDeviceInfo) == 0 ||
             command.compare("di") == 0) {
    err = helper.CallManagerGetDeviceInfo(args);
  } else if (command.compare(kManagerStartRegisterDevice) == 0 ||
             command.compare("sr") == 0) {
    err = helper.CallManagerStartRegisterDevice(args);
  } else if (command.compare(kManagerFinishRegisterDevice) == 0 ||
             command.compare("fr") == 0) {
    err = helper.CallManagerFinishRegisterDevice(args);
  } else if (command.compare(kManagerUpdateStateMethod) == 0 ||
             command.compare("us") == 0) {
    err = helper.CallManagerUpdateState(args);
  } else if (command.compare(kManagerAddCommand) == 0 ||
             command.compare("ac") == 0) {
    err = helper.CallManagerAddCommand(args);
  } else if (command.compare(dbus::kObjectManagerGetManagedObjects) == 0) {
    err = helper.CallRootGetManagedObjects(args);
  } else {
    std::cerr << "Unknown command: " << command << std::endl;
    usage();
  }

  if (err) {
    std::cerr << "Done, with errors." << std::endl;
  } else {
    std::cout << "Done." << std::endl;
  }
  return err;
}
