// 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 <cstring>
#include <ctype.h>
#include <glib.h>

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

#include <fstream>
#include <string>

#include "image_burner.h"
#include "marshal.h"

namespace imageburn {
#include "image-burner/bindings/server.h"

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,
                   image_burner_VOID__STRING_INT64_INT64, 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,
                   image_burner_VOID__STRING_BOOLEAN_STRING, 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 (!signals_ || !image_burner_) {
    LOG(WARNING) << "Finished signal not send due to sender not being "
                 << "initialized";
    return;
  }
  g_signal_emit(image_burner_,
                signals_[kSignalBurnFinished],
                0, target_path, success, error_message);
}

void ImageBurnService::SendProgressSignal(int64 amount_burnt, int64 total_size,
                                          const char* target_path) {
  if (!signals_ || !image_burner_) {
    LOG(WARNING) << "Progresssignal not send 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
