/* Copyright (c) 2013 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 <dbus/dbus.h>
#include <gtest/gtest.h>
#include <stdio.h>
#include <sys/socket.h>

#include "dbus_test.h"

extern "C" {
#include "cras_bt_constants.h"
#include "cras_bt_profile.h"
}

namespace {

static struct cras_bt_profile fake_profile;
static struct cras_bt_transport* fake_transport;
static int profile_release_called;
static struct cras_bt_profile* profile_release_arg_value;
static int profile_new_connection_called;
static struct cras_bt_transport* profile_new_connection_arg_value;
static int profile_request_disconnection_called;
static struct cras_bt_transport* profile_request_disconnection_arg_value;
static int profile_cancel_called;
static struct cras_bt_profile* profile_cancel_arg_value;
static int cras_bt_transport_get_called;
static const char* cras_bt_transport_get_arg_value;

void fake_profile_release(struct cras_bt_profile* profile);
void fake_profile_new_connection(struct cras_bt_profile* profile,
                                 struct cras_bt_transport* transport);
void fake_profile_request_disconnection(struct cras_bt_profile* profile,
                                        struct cras_bt_transport* transport);
void fake_profile_cancel(struct cras_bt_profile* profile);

class BtProfileTestSuite : public DBusTest {
  virtual void SetUp() {
    DBusTest::SetUp();

    profile_release_called = 0;
    profile_new_connection_called = 0;
    profile_request_disconnection_called = 0;
    profile_cancel_called = 0;

    fake_profile.name = "fake";
    fake_profile.object_path = "/fake";
    fake_profile.uuid = "0";
    fake_profile.version = 0;
    fake_profile.role = NULL;
    fake_profile.features = 0;
    fake_profile.release = fake_profile_release;
    fake_profile.new_connection = fake_profile_new_connection;
    fake_profile.request_disconnection = fake_profile_request_disconnection;
    fake_profile.cancel = fake_profile_cancel;

    fake_transport = reinterpret_cast<struct cras_bt_transport*>(0x321);
    cras_bt_transport_get_called = 0;
  }
};

TEST_F(BtProfileTestSuite, RegisterProfile) {
  struct cras_bt_profile* profile;

  ExpectMethodCall(PROFILE_MANAGER_OBJ_PATH, BLUEZ_PROFILE_MGMT_INTERFACE,
                   "RegisterProfile")
      .WithObjectPath("/fake")
      .SendReply();

  cras_bt_add_profile(conn_, &fake_profile);
  cras_bt_register_profiles(conn_);

  WaitForMatches();
  profile = cras_bt_profile_get("/fake");

  EXPECT_TRUE(profile == &fake_profile);
}

TEST_F(BtProfileTestSuite, ResetProfile) {
  cras_bt_add_profile(conn_, &fake_profile);
  cras_bt_profile_reset();

  ASSERT_EQ(1, profile_release_called);
}

TEST_F(BtProfileTestSuite, HandleMessage) {
  ExpectMethodCall(PROFILE_MANAGER_OBJ_PATH, BLUEZ_PROFILE_MGMT_INTERFACE,
                   "RegisterProfile")
      .WithObjectPath("/fake")
      .SendReply();

  cras_bt_add_profile(conn_, &fake_profile);
  cras_bt_register_profiles(conn_);

  WaitForMatches();

  /* Use stdin as mock fd */
  CreateMessageCall("/fake", "org.bluez.Profile1", "NewConnection")
      .WithString("device")
      .WithUnixFd(0)
      .Send();

  WaitForMatches();
  ASSERT_EQ(1, profile_new_connection_called);
  ASSERT_STREQ("device", cras_bt_transport_get_arg_value);
  ASSERT_EQ(1, cras_bt_transport_get_called);
  ASSERT_EQ(fake_transport, profile_new_connection_arg_value);

  CreateMessageCall("/fake", "org.bluez.Profile1", "RequestDisconnection")
      .WithString("device")
      .Send();
  WaitForMatches();
  ASSERT_EQ(2, cras_bt_transport_get_called);
  ASSERT_EQ(1, profile_request_disconnection_called);
  ASSERT_EQ(fake_transport, profile_request_disconnection_arg_value);

  CreateMessageCall("/fake", "org.bluez.Profile1", "Release").Send();
  WaitForMatches();
  ASSERT_EQ(1, profile_release_called);
  ASSERT_EQ(&fake_profile, profile_release_arg_value);

  CreateMessageCall("/fake", "org.bluez.Profile1", "Cancel").Send();
  WaitForMatches();
  ASSERT_EQ(1, profile_cancel_called);
  ASSERT_EQ(&fake_profile, profile_cancel_arg_value);
}

void fake_profile_release(struct cras_bt_profile* profile) {
  profile_release_arg_value = profile;
  profile_release_called++;
}

void fake_profile_new_connection(struct cras_bt_profile* profile,
                                 struct cras_bt_transport* transport) {
  profile_new_connection_arg_value = transport;
  profile_new_connection_called++;
}

void fake_profile_request_disconnection(struct cras_bt_profile* profile,
                                        struct cras_bt_transport* transport) {
  profile_request_disconnection_arg_value = transport;
  profile_request_disconnection_called++;
}

void fake_profile_cancel(struct cras_bt_profile* profile) {
  profile_cancel_arg_value = profile;
  profile_cancel_called++;
}

}  // namespace

extern "C" {
dbus_bool_t append_key_value(DBusMessageIter* iter,
                             const char* key,
                             int type,
                             const char* type_string,
                             void* value) {
  return TRUE;
}

struct cras_bt_transport* cras_bt_transport_get(const char* object_path) {
  cras_bt_transport_get_called++;
  cras_bt_transport_get_arg_value = object_path;
  return fake_transport;
}

void cras_bt_transport_destroy(struct cras_bt_transport* transport) {}

struct cras_bt_transport* cras_bt_transport_create(DBusConnection* conn,
                                                   const char* object_path) {
  return fake_transport;
}

}  // extern "C"

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
