// 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/data_encoding.h>
#include <chromeos/dbus_utils.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/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 << "  " << 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, std::unique_ptr<base::Value>(
                base::Value::CreateStringValue(pair.second))));
      }
    }

    dbus::MethodCall method_call(
        kManagerInterface, kManagerStartRegisterDevice);
    dbus::MessageWriter writer(&method_call);
    chromeos::dbus_utils::AppendValueToWriter(&writer, params);

    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 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(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;
}
