// 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 "image-burner/image_burn_service.h"

#include <ctype.h>
#include <glib.h>

#include <string>

#include <base/logging.h>
#include <dbus/dbus-glib-lowlevel.h>

#include "image-burner/image_burner.h"

namespace imageburn {
#include "bindings/image_burner.dbusserver.h"  // NOLINT(build/include_alpha)

namespace {
// Update signal is emitted only when there is at least
// |kProgressSignalInterval| bytes progress.
const int kProgressSignalInterval = 100*1024;  // 100 KB
}  // namespace

ImageBurnService::ImageBurnService(BurnerImpl* burner_impl)
    : image_burner_(),
      main_loop_(NULL),
      amount_burnt_for_next_signal_(0),
      burning_(false),
      burner_impl_(burner_impl) {
  LOG(INFO) << "Image Burn Service created";
}

ImageBurnService::~ImageBurnService() {
  Cleanup();
}

const char *ImageBurnService::service_name() const {
  return kImageBurnServiceName;
}

const char *ImageBurnService::service_path() const {
  return kImageBurnServicePath;
}

const char *ImageBurnService::service_interface() const {
  return kImageBurnServiceInterface;
}

GObject *ImageBurnService::service_object() const {
  return G_OBJECT(image_burner_);
}

bool ImageBurnService::Initialize() {
  // Install the type-info for the service with dbus.
  dbus_g_object_type_install_info(image_burner_get_type(),
                                  &dbus_glib_image_burner_object_info);

  signals_[kSignalBurnUpdate] =
      g_signal_new(kSignalBurnUpdateName,
                   image_burner_get_type(),
                   G_SIGNAL_RUN_FIRST,
                   0, NULL, NULL,
                   nullptr, G_TYPE_NONE,
                   3, G_TYPE_STRING, G_TYPE_INT64, G_TYPE_INT64);
  signals_[kSignalBurnFinished] =
      g_signal_new(kSignalBurnFinishedName,
                   image_burner_get_type(),
                   G_SIGNAL_RUN_FIRST,
                   0, NULL, NULL,
                   nullptr, G_TYPE_NONE,
                   3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING);

  return Reset();
}

bool ImageBurnService::Reset() {
  LOG(INFO) << "Reseting Image Burn Service";
  Cleanup();

  image_burner_ = reinterpret_cast<ImageBurner*>(
      g_object_new(image_burner_get_type(), NULL));
  // Allow references to this instance.
  image_burner_->service = this;

  main_loop_ = g_main_loop_new(NULL, false);
  if (!main_loop_) {
    LOG(ERROR) << "Failed to create main loop for Image Burn Service";
    return false;
  }
  return true;
}

bool ImageBurnService::Shutdown() {
  return chromeos::dbus::AbstractDbusService::Shutdown();
}

gboolean ImageBurnService::BurnImageAsync(gchar* from_path, gchar* to_path,
    DBusGMethodInvocation * context) {
  std::string error_str;
  bool success = true;
  if (!burner_impl_) {
    error_str = "Burner not set";
    success = false;
  }
  if (!burning_) {
    burning_ = true;
  } else {
    error_str = "Another burn in progress.";
    success = false;
  }

  if (success) {
    dbus_g_method_return(context);
    amount_burnt_for_next_signal_ = 0;
    burner_impl_->BurnImage(from_path, to_path);
    burning_ = false;
  } else {
    GError* error = NULL;
    SetError(error_str, &error);
    dbus_g_method_return_error(context, error);
    g_error_free(error);
    return false;
  }
  return true;
}

void ImageBurnService::Cleanup() {
  if (main_loop_) {
    g_main_loop_unref(main_loop_);
    main_loop_ = NULL;
  }
  if (image_burner_) {
    g_object_unref(image_burner_);
    image_burner_ = NULL;
  }
}

void ImageBurnService::SendFinishedSignal(const char* target_path, bool success,
                                          const char* error_message) {
  if (!image_burner_) {
    LOG(WARNING) << "Finished signal not sent due to sender not being "
                 << "initialized";
    return;
  }
  g_signal_emit(image_burner_,
                signals_[kSignalBurnFinished],
                0, target_path, success, error_message);
}

void ImageBurnService::SendProgressSignal(int64_t amount_burnt,
                                          int64_t total_size,
                                          const char* target_path) {
  if (!image_burner_) {
    LOG(WARNING) << "Progress signal not sent due to sender not being "
                 << "initialized";
    return;
  }
  // Send signal only when there is at least |kProgressSignalInterval| bytes
  // progress.
  if (amount_burnt >= amount_burnt_for_next_signal_) {
    g_signal_emit(image_burner_, signals_[kSignalBurnUpdate], 0, target_path,
                  amount_burnt, total_size);
    amount_burnt_for_next_signal_ = amount_burnt + kProgressSignalInterval;
  }
}

void ImageBurnService::SetError(const std::string& message, GError** error) {
  g_set_error_literal(error, g_quark_from_static_string("image-burn-quark"), 0,
      message.c_str());
}

}  // namespace imageburn
