// Copyright 2013 The Chromium 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/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_nfc_adapter_client.h"
#include "chromeos/dbus/fake_nfc_device_client.h"
#include "chromeos/dbus/fake_nfc_record_client.h"
#include "chromeos/dbus/fake_nfc_tag_client.h"
#include "device/nfc/nfc_adapter_chromeos.h"
#include "device/nfc/nfc_ndef_record.h"
#include "device/nfc/nfc_ndef_record_utils_chromeos.h"
#include "device/nfc/nfc_peer.h"
#include "device/nfc/nfc_tag.h"
#include "device/nfc/nfc_tag_technology.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

using device::NfcAdapter;
using device::NfcNdefMessage;
using device::NfcNdefRecord;
using device::NfcNdefTagTechnology;
using device::NfcPeer;
using device::NfcTag;

namespace chromeos {

namespace {

// Callback passed to property structures.
void OnPropertyChangedCallback(const std::string& property_name) {
}

// Callback passed to dbus::PropertyBase::Set.
void OnSet(bool success) {
}

class TestObserver : public NfcAdapter::Observer,
                     public NfcPeer::Observer,
                     public NfcTag::Observer,
                     public NfcNdefTagTechnology::Observer {
 public:
  TestObserver(scoped_refptr<NfcAdapter> adapter)
      : present_changed_count_(0),
        powered_changed_count_(0),
        polling_changed_count_(0),
        peer_records_received_count_(0),
        tag_records_received_count_(0),
        peer_count_(0),
        tag_count_(0),
        adapter_(adapter) {
  }

  virtual ~TestObserver() {}

  // NfcAdapter::Observer override.
  virtual void AdapterPresentChanged(NfcAdapter* adapter,
                                     bool present) override {
    EXPECT_EQ(adapter_.get(), adapter);
    present_changed_count_++;
  }

  // NfcAdapter::Observer override.
  virtual void AdapterPoweredChanged(NfcAdapter* adapter,
                                     bool powered) override {
    EXPECT_EQ(adapter_.get(), adapter);
    powered_changed_count_++;
  }

  // NfcAdapter::Observer override.
  virtual void AdapterPollingChanged(NfcAdapter* adapter,
                                     bool powered) override {
    EXPECT_EQ(adapter_.get(), adapter);
    polling_changed_count_++;
  }

  // NfcAdapter::Observer override.
  virtual void PeerFound(NfcAdapter* adapter, NfcPeer* peer) override {
    EXPECT_EQ(adapter_.get(), adapter);
    peer_count_++;
    peer_identifier_ = peer->GetIdentifier();
  }

  // NfcAdapter::Observer override.
  virtual void PeerLost(NfcAdapter* adapter, NfcPeer* peer) override {
    EXPECT_EQ(adapter_.get(), adapter);
    EXPECT_EQ(peer_identifier_, peer->GetIdentifier());
    peer_count_--;
    peer_identifier_.clear();
  }

  // NfcAdapter::Observer override.
  virtual void TagFound(NfcAdapter* adapter, NfcTag* tag) override {
    EXPECT_EQ(adapter_.get(), adapter);
    tag_count_++;
    tag_identifier_ = tag->GetIdentifier();
  }

  // NfcAdapter::Observer override.
  virtual void TagLost(NfcAdapter* adapter, NfcTag* tag) override {
    EXPECT_EQ(adapter_.get(), adapter);
    EXPECT_EQ(tag_identifier_, tag->GetIdentifier());
    tag_count_--;
    tag_identifier_.clear();
  }

  // NfcPeer::Observer override.
  virtual void RecordReceived(
      NfcPeer* peer, const NfcNdefRecord* record) override {
    EXPECT_EQ(peer, adapter_->GetPeer(peer_identifier_));
    EXPECT_EQ(peer_identifier_, peer->GetIdentifier());
    peer_records_received_count_++;
  }

  // NfcNdefTagTechnology::Observer override.
  virtual void RecordReceived(
        NfcTag* tag, const NfcNdefRecord* record) override {
    EXPECT_EQ(tag, adapter_->GetTag(tag_identifier_));
    EXPECT_EQ(tag_identifier_, tag->GetIdentifier());
    tag_records_received_count_++;
  }

  int present_changed_count_;
  int powered_changed_count_;
  int polling_changed_count_;
  int peer_records_received_count_;
  int tag_records_received_count_;
  int peer_count_;
  int tag_count_;
  std::string peer_identifier_;
  std::string tag_identifier_;
  scoped_refptr<NfcAdapter> adapter_;
};

}  // namespace

class NfcChromeOSTest : public testing::Test {
 public:
  virtual void SetUp() {
    DBusThreadManager::Initialize();
    fake_nfc_adapter_client_ = static_cast<FakeNfcAdapterClient*>(
        DBusThreadManager::Get()->GetNfcAdapterClient());
    fake_nfc_device_client_ = static_cast<FakeNfcDeviceClient*>(
        DBusThreadManager::Get()->GetNfcDeviceClient());
    fake_nfc_record_client_ = static_cast<FakeNfcRecordClient*>(
        DBusThreadManager::Get()->GetNfcRecordClient());
    fake_nfc_tag_client_ = static_cast<FakeNfcTagClient*>(
        DBusThreadManager::Get()->GetNfcTagClient());

    fake_nfc_adapter_client_->EnablePairingOnPoll(false);
    fake_nfc_device_client_->DisableSimulationTimeout();
    fake_nfc_tag_client_->DisableSimulationTimeout();
    success_callback_count_ = 0;
    error_callback_count_ = 0;
  }

  virtual void TearDown() {
    adapter_ = NULL;
    DBusThreadManager::Shutdown();
  }

  // Assigns a new instance of NfcAdapterChromeOS to |adapter_|.
  void SetAdapter() {
    adapter_ = new NfcAdapterChromeOS();
    ASSERT_TRUE(adapter_.get() != NULL);
    ASSERT_TRUE(adapter_->IsInitialized());
    base::RunLoop().RunUntilIdle();
  }

  // Generic callbacks for success and error.
  void SuccessCallback() {
    success_callback_count_++;
  }

  void ErrorCallback() {
    error_callback_count_++;
  }

  void ErrorCallbackWithParameters(const std::string& error_name,
                                   const std::string& error_message) {
    LOG(INFO) << "Error callback called: " << error_name << ", "
              << error_message;
    error_callback_count_++;
  }

 protected:
  // MessageLoop instance, used to simulate asynchronous behavior.
  base::MessageLoop message_loop_;

  // Fields for storing the number of times SuccessCallback and ErrorCallback
  // have been called.
  int success_callback_count_;
  int error_callback_count_;

  // The NfcAdapter instance under test.
  scoped_refptr<NfcAdapter> adapter_;

  // The fake D-Bus client instances used for testing.
  FakeNfcAdapterClient* fake_nfc_adapter_client_;
  FakeNfcDeviceClient* fake_nfc_device_client_;
  FakeNfcRecordClient* fake_nfc_record_client_;
  FakeNfcTagClient* fake_nfc_tag_client_;
};

// Tests that the adapter updates correctly to reflect the current "default"
// adapter, when multiple adapters appear and disappear.
TEST_F(NfcChromeOSTest, PresentChanged) {
  SetAdapter();
  EXPECT_TRUE(adapter_->IsPresent());

  TestObserver observer(adapter_);
  adapter_->AddObserver(&observer);

  // Remove all adapters.
  fake_nfc_adapter_client_->SetAdapterPresent(false);
  EXPECT_EQ(1, observer.present_changed_count_);
  EXPECT_FALSE(adapter_->IsPresent());

  // Add two adapters.
  fake_nfc_adapter_client_->SetAdapterPresent(true);
  fake_nfc_adapter_client_->SetSecondAdapterPresent(true);
  EXPECT_EQ(2, observer.present_changed_count_);
  EXPECT_TRUE(adapter_->IsPresent());

  // Remove the first adapter. Adapter  should update to the second one.
  fake_nfc_adapter_client_->SetAdapterPresent(false);
  EXPECT_EQ(4, observer.present_changed_count_);
  EXPECT_TRUE(adapter_->IsPresent());

  fake_nfc_adapter_client_->SetSecondAdapterPresent(false);
  EXPECT_EQ(5, observer.present_changed_count_);
  EXPECT_FALSE(adapter_->IsPresent());
}

// Tests that the adapter correctly reflects the power state.
TEST_F(NfcChromeOSTest, SetPowered) {
  SetAdapter();
  TestObserver observer(adapter_);
  adapter_->AddObserver(&observer);

  EXPECT_FALSE(adapter_->IsPowered());

  // SetPowered(false), while not powered.
  adapter_->SetPowered(
      false,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_EQ(0, observer.powered_changed_count_);
  EXPECT_EQ(0, success_callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  // SetPowered(true).
  adapter_->SetPowered(
      true,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_EQ(1, observer.powered_changed_count_);
  EXPECT_EQ(1, success_callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  // SetPowered(true), while powered.
  adapter_->SetPowered(
      true,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_EQ(1, observer.powered_changed_count_);
  EXPECT_EQ(1, success_callback_count_);
  EXPECT_EQ(2, error_callback_count_);

  // SetPowered(false).
  adapter_->SetPowered(
      false,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_EQ(2, observer.powered_changed_count_);
  EXPECT_EQ(2, success_callback_count_);
  EXPECT_EQ(2, error_callback_count_);
}

// Tests that the power state updates correctly when the adapter disappears.
TEST_F(NfcChromeOSTest, PresentChangedWhilePowered) {
  SetAdapter();
  TestObserver observer(adapter_);
  adapter_->AddObserver(&observer);

  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_TRUE(adapter_->IsPresent());

  adapter_->SetPowered(
      true,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_TRUE(adapter_->IsPowered());

  fake_nfc_adapter_client_->SetAdapterPresent(false);
  EXPECT_EQ(1, observer.present_changed_count_);
  EXPECT_EQ(2, observer.powered_changed_count_);
  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_FALSE(adapter_->IsPresent());
}

// Tests that peer and record objects are created for all peers and records
// that already exist when the adapter is created.
TEST_F(NfcChromeOSTest, PeersInitializedWhenAdapterCreated) {
  // Set up the adapter client.
  NfcAdapterClient::Properties* properties =
      fake_nfc_adapter_client_->GetProperties(
          dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0));
  properties->powered.Set(true, base::Bind(&OnSet));

  fake_nfc_adapter_client_->StartPollLoop(
      dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0),
      nfc_adapter::kModeInitiator,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters,
                 base::Unretained(this)));
  EXPECT_EQ(1, success_callback_count_);
  EXPECT_TRUE(properties->powered.value());
  EXPECT_TRUE(properties->polling.value());

  // Start pairing simulation, which will add a fake device and fake records.
  fake_nfc_device_client_->BeginPairingSimulation(0, 0);
  base::RunLoop().RunUntilIdle();

  // Create the adapter.
  SetAdapter();
  TestObserver observer(adapter_);
  adapter_->AddObserver(&observer);

  // Observer shouldn't have received any calls, as it got created AFTER the
  // notifications were sent.
  EXPECT_EQ(0, observer.present_changed_count_);
  EXPECT_EQ(0, observer.powered_changed_count_);
  EXPECT_EQ(0, observer.polling_changed_count_);
  EXPECT_EQ(0, observer.peer_count_);

  EXPECT_TRUE(adapter_->IsPresent());
  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_FALSE(adapter_->IsPolling());

  NfcAdapter::PeerList peers;
  adapter_->GetPeers(&peers);
  EXPECT_EQ(static_cast<size_t>(1), peers.size());

  NfcPeer* peer = peers[0];
  const NfcNdefMessage& message = peer->GetNdefMessage();
  EXPECT_EQ(static_cast<size_t>(3), message.records().size());
}

// Tests that tag and record objects are created for all tags and records that
// already exist when the adapter is created.
TEST_F(NfcChromeOSTest, TagsInitializedWhenAdapterCreated) {
  const char kTestURI[] = "fake://path/for/testing";

  // Set up the adapter client.
  NfcAdapterClient::Properties* properties =
      fake_nfc_adapter_client_->GetProperties(
          dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0));
  properties->powered.Set(true, base::Bind(&OnSet));

  fake_nfc_adapter_client_->StartPollLoop(
      dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0),
      nfc_adapter::kModeInitiator,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters,
                 base::Unretained(this)));
  EXPECT_EQ(1, success_callback_count_);
  EXPECT_TRUE(properties->powered.value());
  EXPECT_TRUE(properties->polling.value());

  // Add the fake tag.
  fake_nfc_tag_client_->BeginPairingSimulation(0);
  base::RunLoop().RunUntilIdle();

  // Create a fake record.
  base::DictionaryValue test_record_data;
  test_record_data.SetString(nfc_record::kTypeProperty, nfc_record::kTypeUri);
  test_record_data.SetString(nfc_record::kUriProperty, kTestURI);
  fake_nfc_tag_client_->Write(
      dbus::ObjectPath(FakeNfcTagClient::kTagPath),
      test_record_data,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters,
                 base::Unretained(this)));
  EXPECT_EQ(2, success_callback_count_);

  // Create the adapter.
  SetAdapter();
  TestObserver observer(adapter_);
  adapter_->AddObserver(&observer);

  // Observer shouldn't have received any calls, as it got created AFTER the
  // notifications were sent.
  EXPECT_EQ(0, observer.present_changed_count_);
  EXPECT_EQ(0, observer.powered_changed_count_);
  EXPECT_EQ(0, observer.polling_changed_count_);
  EXPECT_EQ(0, observer.peer_count_);

  EXPECT_TRUE(adapter_->IsPresent());
  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_FALSE(adapter_->IsPolling());

  NfcAdapter::TagList tags;
  adapter_->GetTags(&tags);
  EXPECT_EQ(static_cast<size_t>(1), tags.size());

  NfcTag* tag = tags[0];
  const NfcNdefMessage& message = tag->GetNdefTagTechnology()->GetNdefMessage();
  EXPECT_EQ(static_cast<size_t>(1), message.records().size());

  const NfcNdefRecord* record = message.records()[0];
  std::string uri;
  EXPECT_TRUE(record->data().GetString(NfcNdefRecord::kFieldURI, &uri));
  EXPECT_EQ(kTestURI, uri);
}

// Tests that the adapter correctly updates its state when polling is started
// and stopped.
TEST_F(NfcChromeOSTest, StartAndStopPolling) {
  SetAdapter();
  EXPECT_TRUE(adapter_->IsPresent());

  TestObserver observer(adapter_);
  adapter_->AddObserver(&observer);

  // Start polling while not powered. Should fail.
  EXPECT_FALSE(adapter_->IsPowered());
  adapter_->StartPolling(
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(0, success_callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_FALSE(adapter_->IsPolling());

  // Start polling while powered. Should succeed.
  adapter_->SetPowered(
      true,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(1, success_callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPowered());

  adapter_->StartPolling(
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(2, success_callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPolling());

  // Start polling while already polling. Should fail.
  adapter_->StartPolling(
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(2, success_callback_count_);
  EXPECT_EQ(2, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPolling());

  // Stop polling. Should succeed.
  adapter_->StopPolling(
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(3, success_callback_count_);
  EXPECT_EQ(2, error_callback_count_);
  EXPECT_FALSE(adapter_->IsPolling());

  // Stop polling while not polling. Should fail.
  adapter_->StopPolling(
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(3, success_callback_count_);
  EXPECT_EQ(3, error_callback_count_);
  EXPECT_FALSE(adapter_->IsPolling());
}

// Tests a simple peer pairing simulation.
TEST_F(NfcChromeOSTest, PeerTest) {
  SetAdapter();
  TestObserver observer(adapter_);
  adapter_->AddObserver(&observer);

  adapter_->SetPowered(
      true,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  adapter_->StartPolling(
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(2, success_callback_count_);

  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_TRUE(adapter_->IsPolling());
  EXPECT_EQ(0, observer.peer_count_);

  // Add the fake device.
  fake_nfc_device_client_->BeginPairingSimulation(0, -1);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, observer.peer_count_);
  EXPECT_EQ(FakeNfcDeviceClient::kDevicePath, observer.peer_identifier_);

  NfcPeer* peer = adapter_->GetPeer(observer.peer_identifier_);
  CHECK(peer);
  peer->AddObserver(&observer);

  // Peer should have no records on it.
  EXPECT_TRUE(peer->GetNdefMessage().records().empty());
  EXPECT_EQ(0, observer.peer_records_received_count_);

  // Make records visible.
  fake_nfc_record_client_->SetDeviceRecordsVisible(true);
  EXPECT_EQ(3, observer.peer_records_received_count_);
  EXPECT_EQ(static_cast<size_t>(3), peer->GetNdefMessage().records().size());

  // End the simulation. Peer should get removed.
  fake_nfc_device_client_->EndPairingSimulation();
  EXPECT_EQ(0, observer.peer_count_);
  EXPECT_TRUE(observer.peer_identifier_.empty());

  peer = adapter_->GetPeer(observer.peer_identifier_);
  EXPECT_FALSE(peer);

  // No record related notifications will be sent when a peer gets removed.
  EXPECT_EQ(3, observer.peer_records_received_count_);
}

// Tests a simple tag pairing simulation.
TEST_F(NfcChromeOSTest, TagTest) {
  const char kTestURI[] = "fake://path/for/testing";

  SetAdapter();
  TestObserver observer(adapter_);
  adapter_->AddObserver(&observer);

  adapter_->SetPowered(
      true,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  adapter_->StartPolling(
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(2, success_callback_count_);

  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_TRUE(adapter_->IsPolling());
  EXPECT_EQ(0, observer.tag_count_);

  // Add the fake tag.
  fake_nfc_tag_client_->BeginPairingSimulation(0);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, observer.tag_count_);
  EXPECT_EQ(FakeNfcTagClient::kTagPath, observer.tag_identifier_);

  NfcTag* tag = adapter_->GetTag(observer.tag_identifier_);
  CHECK(tag);
  tag->AddObserver(&observer);
  EXPECT_TRUE(tag->IsReady());
  CHECK(tag->GetNdefTagTechnology());
  tag->GetNdefTagTechnology()->AddObserver(&observer);

  NfcNdefTagTechnology* tag_technology = tag->GetNdefTagTechnology();
  EXPECT_TRUE(tag_technology->IsSupportedByTag());

  // Tag should have no records on it.
  EXPECT_TRUE(tag_technology->GetNdefMessage().records().empty());
  EXPECT_EQ(0, observer.tag_records_received_count_);

  // Set the tag record visible. By default the record has no content, so no
  // NfcNdefMessage should be received.
  fake_nfc_record_client_->SetTagRecordsVisible(true);
  EXPECT_TRUE(tag_technology->GetNdefMessage().records().empty());
  EXPECT_EQ(0, observer.tag_records_received_count_);
  fake_nfc_record_client_->SetTagRecordsVisible(false);

  // Write an NDEF record to the tag.
  EXPECT_EQ(2, success_callback_count_);  // 2 for SetPowered and StartPolling.
  EXPECT_EQ(0, error_callback_count_);

  base::DictionaryValue record_data;
  record_data.SetString(NfcNdefRecord::kFieldURI, kTestURI);
  NfcNdefRecord written_record;
  written_record.Populate(NfcNdefRecord::kTypeURI, &record_data);
  NfcNdefMessage written_message;
  written_message.AddRecord(&written_record);

  tag_technology->WriteNdef(
      written_message,
      base::Bind(&NfcChromeOSTest::SuccessCallback,
                 base::Unretained(this)),
      base::Bind(&NfcChromeOSTest::ErrorCallback,
                 base::Unretained(this)));
  EXPECT_EQ(3, success_callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(static_cast<size_t>(1),
            tag_technology->GetNdefMessage().records().size());
  EXPECT_EQ(1, observer.tag_records_received_count_);

  NfcNdefRecord* received_record =
      tag_technology->GetNdefMessage().records()[0];
  EXPECT_EQ(NfcNdefRecord::kTypeURI, received_record->type());
  std::string uri;
  EXPECT_TRUE(received_record->data().GetString(
      NfcNdefRecord::kFieldURI, &uri));
  EXPECT_EQ(kTestURI, uri);

  // End the simulation. Tag should get removed.
  fake_nfc_tag_client_->EndPairingSimulation();
  EXPECT_EQ(0, observer.tag_count_);
  EXPECT_TRUE(observer.tag_identifier_.empty());

  tag = adapter_->GetTag(observer.tag_identifier_);
  EXPECT_FALSE(tag);

  // No record related notifications will be sent when a tag gets removed.
  EXPECT_EQ(1, observer.tag_records_received_count_);
}

// Unit tests for nfc_ndef_record_utils methods.
TEST_F(NfcChromeOSTest, NfcNdefRecordToDBusAttributes) {
  const char kText[] = "text";
  const char kURI[] = "test://uri";
  const char kEncoding[] = "encoding";
  const char kLanguageCode[] = "en";
  const char kMimeType[] = "mime-type";
  const double kSize = 5;

  // Text record.
  base::DictionaryValue data;
  data.SetString(NfcNdefRecord::kFieldText, kText);
  data.SetString(NfcNdefRecord::kFieldLanguageCode, kLanguageCode);
  data.SetString(NfcNdefRecord::kFieldEncoding, kEncoding);

  scoped_ptr<NfcNdefRecord> record(new NfcNdefRecord());
  ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeText, &data));

  base::DictionaryValue result;
  EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
      record.get(), &result));

  std::string string_value;
  EXPECT_TRUE(result.GetString(
      nfc_record::kTypeProperty, &string_value));
  EXPECT_EQ(nfc_record::kTypeText, string_value);
  EXPECT_TRUE(result.GetString(
      nfc_record::kRepresentationProperty, &string_value));
  EXPECT_EQ(kText, string_value);
  EXPECT_TRUE(result.GetString(
      nfc_record::kLanguageProperty, &string_value));
  EXPECT_EQ(kLanguageCode, string_value);
  EXPECT_TRUE(result.GetString(
      nfc_record::kEncodingProperty, &string_value));
  EXPECT_EQ(kEncoding, string_value);

  // URI record.
  data.Clear();
  data.SetString(NfcNdefRecord::kFieldURI, kURI);
  data.SetString(NfcNdefRecord::kFieldMimeType, kMimeType);
  data.SetDouble(NfcNdefRecord::kFieldTargetSize, kSize);

  record.reset(new NfcNdefRecord());
  ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeURI, &data));

  result.Clear();
  EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
      record.get(), &result));

  EXPECT_TRUE(result.GetString(nfc_record::kTypeProperty, &string_value));
  EXPECT_EQ(nfc_record::kTypeUri, string_value);
  EXPECT_TRUE(result.GetString(nfc_record::kUriProperty, &string_value));
  EXPECT_EQ(kURI, string_value);
  EXPECT_TRUE(result.GetString(nfc_record::kMimeTypeProperty, &string_value));
  EXPECT_EQ(kMimeType, string_value);
  double double_value;
  EXPECT_TRUE(result.GetDouble(nfc_record::kSizeProperty, &double_value));
  EXPECT_EQ(kSize, double_value);

  // SmartPoster record.
  base::DictionaryValue* title = new base::DictionaryValue();
  title->SetString(NfcNdefRecord::kFieldText, kText);
  title->SetString(NfcNdefRecord::kFieldLanguageCode, kLanguageCode);
  title->SetString(NfcNdefRecord::kFieldEncoding, kEncoding);

  base::ListValue* titles = new base::ListValue();
  titles->Append(title);
  data.Set(NfcNdefRecord::kFieldTitles, titles);

  record.reset(new NfcNdefRecord());
  ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));

  result.Clear();
  EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
      record.get(), &result));

  EXPECT_TRUE(result.GetString(
      nfc_record::kTypeProperty, &string_value));
  EXPECT_EQ(nfc_record::kTypeSmartPoster, string_value);
  EXPECT_TRUE(result.GetString(
      nfc_record::kRepresentationProperty, &string_value));
  EXPECT_EQ(kText, string_value);
  EXPECT_TRUE(result.GetString(
      nfc_record::kLanguageProperty, &string_value));
  EXPECT_EQ(kLanguageCode, string_value);
  EXPECT_TRUE(result.GetString(
      nfc_record::kEncodingProperty, &string_value));
  EXPECT_EQ(kEncoding, string_value);
  EXPECT_TRUE(result.GetString(nfc_record::kUriProperty, &string_value));
  EXPECT_EQ(kURI, string_value);
  EXPECT_TRUE(result.GetString(nfc_record::kMimeTypeProperty, &string_value));
  EXPECT_EQ(kMimeType, string_value);
  EXPECT_TRUE(result.GetDouble(nfc_record::kSizeProperty, &double_value));
  EXPECT_EQ(kSize, double_value);
}

TEST_F(NfcChromeOSTest, RecordPropertiesToNfcNdefRecord) {
  const char kText[] = "text";
  const char kURI[] = "test://uri";
  const char kEncoding[] = "encoding";
  const char kLanguageCode[] = "en";
  const char kMimeType[] = "mime-type";
  const uint32 kSize = 5;

  FakeNfcRecordClient::Properties record_properties(
      base::Bind(&OnPropertyChangedCallback));

  // Text record.
  record_properties.type.ReplaceValue(nfc_record::kTypeText);
  record_properties.representation.ReplaceValue(kText);
  record_properties.language.ReplaceValue(kLanguageCode);
  record_properties.encoding.ReplaceValue(kEncoding);

  scoped_ptr<NfcNdefRecord> record(new NfcNdefRecord());
  EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
      &record_properties, record.get()));
  EXPECT_TRUE(record->IsPopulated());

  std::string string_value;
  EXPECT_EQ(NfcNdefRecord::kTypeText, record->type());
  EXPECT_TRUE(record->data().GetString(
      NfcNdefRecord::kFieldText, &string_value));
  EXPECT_EQ(kText, string_value);
  EXPECT_TRUE(record->data().GetString(
      NfcNdefRecord::kFieldLanguageCode, &string_value));
  EXPECT_EQ(kLanguageCode, string_value);
  EXPECT_TRUE(record->data().GetString(
      NfcNdefRecord::kFieldEncoding, &string_value));
  EXPECT_EQ(kEncoding, string_value);

  // URI record.
  record_properties.representation.ReplaceValue("");
  record_properties.language.ReplaceValue("");
  record_properties.encoding.ReplaceValue("");

  record_properties.type.ReplaceValue(nfc_record::kTypeUri);
  record_properties.uri.ReplaceValue(kURI);
  record_properties.mime_type.ReplaceValue(kMimeType);
  record_properties.size.ReplaceValue(kSize);

  record.reset(new NfcNdefRecord());
  EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
      &record_properties, record.get()));
  EXPECT_TRUE(record->IsPopulated());

  EXPECT_EQ(NfcNdefRecord::kTypeURI, record->type());
  EXPECT_TRUE(record->data().GetString(
      NfcNdefRecord::kFieldURI, &string_value));
  EXPECT_EQ(kURI, string_value);
  EXPECT_TRUE(record->data().GetString(
      NfcNdefRecord::kFieldMimeType, &string_value));
  EXPECT_EQ(kMimeType, string_value);
  double double_value;
  EXPECT_TRUE(record->data().GetDouble(
      NfcNdefRecord::kFieldTargetSize, &double_value));
  EXPECT_EQ(kSize, double_value);

  // Contents not matching type.
  record_properties.representation.ReplaceValue(kText);
  record_properties.language.ReplaceValue(kLanguageCode);
  record_properties.encoding.ReplaceValue(kEncoding);

  record.reset(new NfcNdefRecord());
  EXPECT_FALSE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
      &record_properties, record.get()));
  EXPECT_FALSE(record->IsPopulated());

  // SmartPoster record.
  record_properties.type.ReplaceValue(nfc_record::kTypeSmartPoster);
  EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
      &record_properties, record.get()));
  EXPECT_TRUE(record->IsPopulated());

  EXPECT_EQ(NfcNdefRecord::kTypeSmartPoster, record->type());
  EXPECT_TRUE(record->data().GetString(
      NfcNdefRecord::kFieldURI, &string_value));
  EXPECT_EQ(kURI, string_value);
  EXPECT_TRUE(record->data().GetString(
      NfcNdefRecord::kFieldMimeType, &string_value));
  EXPECT_EQ(kMimeType, string_value);
  EXPECT_TRUE(record->data().GetDouble(
      NfcNdefRecord::kFieldTargetSize, &double_value));
  EXPECT_EQ(kSize, double_value);

  const base::ListValue* titles = NULL;
  EXPECT_TRUE(record->data().GetList(NfcNdefRecord::kFieldTitles, &titles));
  EXPECT_EQ(static_cast<size_t>(1), titles->GetSize());
  ASSERT_TRUE(titles);
  const base::DictionaryValue* title = NULL;
  EXPECT_TRUE(titles->GetDictionary(0, &title));
  CHECK(title);

  EXPECT_TRUE(title->GetString(NfcNdefRecord::kFieldText, &string_value));
  EXPECT_EQ(kText, string_value);
  EXPECT_TRUE(title->GetString(
      NfcNdefRecord::kFieldLanguageCode, &string_value));
  EXPECT_EQ(kLanguageCode, string_value);
  EXPECT_TRUE(title->GetString(NfcNdefRecord::kFieldEncoding, &string_value));
  EXPECT_EQ(kEncoding, string_value);
}

}  // namespace chromeos
