// Copyright (c) 2011 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 <base/basictypes.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <chromeos/dbus/dbus.h>
#include <chromeos/dbus/service_constants.h>
#include <fstream>
#include <glib.h>
#include <iostream>
#include <vector>
#include <utility>
#include <string>

#include "image-burner/marshal.h"
#include "image-burner/bindings/client.h"


namespace chromeos {

static const char* const kImgSrc =
    "/home/chronos/user/Downloads/chromeos_image.imgburn.test";

class TestClient {
 public:
  typedef dbus::MonitorConnection<void(const char*, const int64, const int64)>*
      ConnectionUpdateType;
  typedef dbus::MonitorConnection<void(const char*, const bool, const char*)>*
      ConnectionFinishedType;
  static void Update(void* object, const char* target_path,
                     const int64 amount_burnt, const int64 total_size) {
    std::cout << target_path << " " << amount_burnt << " "
              <<total_size << std::endl;
    flush(std::cout);
  }

  TestClient(dbus::Proxy proxy, GMainLoop* loop) : burn_proxy_(proxy),
                                                   loop_(loop),
                                                   tests_it_(tests_.end()) {
    ::dbus_g_proxy_add_signal(burn_proxy_.gproxy(),
                              "burn_progress_update",
                              G_TYPE_STRING,
                              G_TYPE_INT64,
                              G_TYPE_INT64,
                              G_TYPE_INVALID);

    typedef dbus::MonitorConnection<void(const char*, const int64, const int64)>
       ConnectionUpdateTypeRef;
    ConnectionUpdateTypeRef *update =
        new ConnectionUpdateTypeRef(burn_proxy_, "burn_progress_update",
                                    &TestClient::Update, this);
    ::dbus_g_proxy_connect_signal(burn_proxy_.gproxy(),
                                  "burn_progress_update",
                                  G_CALLBACK(&ConnectionUpdateTypeRef::Run),
                                  update, NULL);
    updateconnection_ = update;

    // adding finished signal and connection
    ::dbus_g_proxy_add_signal(burn_proxy_.gproxy(),
                              "burn_finished",
                              G_TYPE_STRING,
                              G_TYPE_BOOLEAN,
                              G_TYPE_STRING,
                              G_TYPE_INVALID);

    typedef dbus::MonitorConnection<void(const char*, const bool, const char*)>
        ConnectionFinishTypeRef;
    ConnectionFinishTypeRef *finished =
        new ConnectionFinishTypeRef(burn_proxy_, "burn_finished",
                                    &TestClient::Finished, this);
    ::dbus_g_proxy_connect_signal(burn_proxy_.gproxy(),
                                  "burn_finished",
                                  G_CALLBACK(&ConnectionFinishTypeRef::Run),
                                  finished, NULL);
    finishedconnection_ = finished;
  }


  ~TestClient() {
    dbus::Disconnect(updateconnection_);
    dbus::Disconnect(finishedconnection_);
  }

  void StartTests() {
    tests_.resize(0);
    expects_.resize(0);
    failed_ = false;


    foo_source = std::fopen(kImgSrc, "w");
    for (int i = 0; i < 1000000; i++)
      std::fwrite(&i, sizeof(i), 1, foo_source);
    std::fclose(foo_source);

    AddTest(kImgSrc, "/dev/sdb", true);

    tests_it_ = tests_.begin();
    expects_it_ = expects_.begin();
    RunNext();
  }

  void RunNext() {
    if (tests_it_ == tests_.end()) {
      std::cout << (failed_ ? "********** TESTS FAILED *********" :
          "********** TESTS SUCCEDED **********") << std::endl;
      std::remove(kImgSrc);
      ::g_main_loop_quit(loop_);
    } else {
      std::cout << "Running next test" << std::endl;
      RunOne();
    }
  }

 private:
  void AddTest(const char* to, const char* from, bool expected_success) {
    tests_.push_back(std::make_pair(to, from));
    expects_.push_back(expected_success);
  }

 static void TestRunCallback(DBusGProxy* gproxy, DBusGProxyCall* call_id,
      void* user_data) {
    TestClient* self = static_cast<TestClient*>(user_data);
    glib::ScopedError error;
    if (!::dbus_g_proxy_end_call(gproxy, call_id, &Resetter(&error).lvalue(),
        G_TYPE_INVALID)) {
      std::cout << "Burning failed: " << error->message << std::endl;
      if (*self->expects_it_) {
        self->failed_ = true;
        std::cout << "FAIL" << std::endl;
      } else {
        std::cout << "OK" << std::endl;
      }
      ++self->expects_it_;
      ++self->tests_it_;
      self->RunNext();
      return;
    }
    std::cout << "Burning started" << std::endl;
    if (!(*self->expects_it_)) {
      self->failed_ = true;
      std::cout << "FAIL" << std::endl;
    }
    ++self->tests_it_;
    ++self->expects_it_;
  }

  void RunOne() {
    glib::ScopedError error;
    std::cout << "start" << std::endl;
    if (!::dbus_g_proxy_begin_call(burn_proxy_.gproxy(), "BurnImage",
        &TestRunCallback,
        this, NULL,
        G_TYPE_STRING, tests_it_->first.c_str(),
        G_TYPE_STRING, tests_it_->second.c_str(),
        G_TYPE_INVALID)) {
      std::cout << "Burn call failed." << std::endl;
      std::cout << "FAIL" << std::endl;
      failed_ = true;
      ++expects_it_;
      ++tests_it_;
      RunNext();
    }
  }

  static void Finished(void* object, const char* target_path,
                       const bool success, const char* error ) {
    TestClient* self = static_cast<TestClient*>(object);
    if (success) {
      std::cout << "OK" << std::endl;
    } else {
      self->failed_ = true;
      std::cout << "FAIL" << std::endl;
    }
    self->RunNext();
  }

  dbus::Proxy burn_proxy_;
  GMainLoop *loop_;
  ConnectionUpdateType updateconnection_;
  ConnectionFinishedType finishedconnection_;
  typedef std::vector<std::pair<std::string, std::string> > IBTestVec;
  IBTestVec tests_;
  IBTestVec::iterator tests_it_;
  typedef std::vector<bool> ExpectedSuccessVec;
  ExpectedSuccessVec expects_;
  ExpectedSuccessVec::iterator expects_it_;
  bool failed_;
  FILE* foo_source;

};

}  // namespace chromeos

int main(int argc, char* argv[]) {
  ::g_type_init();
  GMainLoop* loop = ::g_main_loop_new(NULL, true);
  dbus_g_object_register_marshaller(image_burner_VOID__STRING_BOOLEAN_STRING,
                                    G_TYPE_NONE,
                                    G_TYPE_STRING,
                                    G_TYPE_BOOLEAN,
                                    G_TYPE_STRING,
                                    G_TYPE_INVALID);
  dbus_g_object_register_marshaller(image_burner_VOID__STRING_INT64_INT64,
                                    G_TYPE_NONE,
                                    G_TYPE_STRING,
                                    G_TYPE_INT64,
                                    G_TYPE_INT64,
                                    G_TYPE_INVALID);

  chromeos::dbus::BusConnection bus = chromeos::dbus::GetSystemBusConnection();
  chromeos::dbus::Proxy burn_proxy(bus,
                                  "org.chromium.ImageBurner",
                                  "/org/chromium/ImageBurner",
                                  "org.chromium.ImageBurnerInterface");
  chromeos::TestClient test(burn_proxy, loop);

  test.StartTests();
  ::g_main_loop_run(loop);

  return 0;
}

