// Copyright (c) 2011 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 "ipc/ipc_test_sink.h"

#include <stddef.h>
#include <stdint.h>

#include "build/build_config.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"

namespace IPC {

TestSink::TestSink() {
}

TestSink::~TestSink() {
}

bool TestSink::Send(Message* message) {
  OnMessageReceived(*message);
  delete message;
  return true;
}

bool TestSink::Connect() {
  NOTIMPLEMENTED();
  return false;
}

void TestSink::Close() {
  NOTIMPLEMENTED();
}

base::ProcessId TestSink::GetPeerPID() const {
  NOTIMPLEMENTED();
  return base::ProcessId();
}

base::ProcessId TestSink::GetSelfPID() const {
  NOTIMPLEMENTED();
  return base::ProcessId();
}

bool TestSink::OnMessageReceived(const Message& msg) {
  base::ObserverListBase<Listener>::Iterator it(&filter_list_);
  Listener* observer;
  while ((observer = it.GetNext()) != NULL) {
    if (observer->OnMessageReceived(msg))
      return true;
  }

  // No filter handled the message, so store it.
  messages_.push_back(Message(msg));
  return true;
}

void TestSink::ClearMessages() {
  messages_.clear();
}

const Message* TestSink::GetMessageAt(size_t index) const {
  if (index >= messages_.size())
    return NULL;
  return &messages_[index];
}

const Message* TestSink::GetFirstMessageMatching(uint32_t id) const {
  for (size_t i = 0; i < messages_.size(); i++) {
    if (messages_[i].type() == id)
      return &messages_[i];
  }
  return NULL;
}

const Message* TestSink::GetUniqueMessageMatching(uint32_t id) const {
  size_t found_index = 0;
  size_t found_count = 0;
  for (size_t i = 0; i < messages_.size(); i++) {
    if (messages_[i].type() == id) {
      found_count++;
      found_index = i;
    }
  }
  if (found_count != 1)
    return NULL;  // Didn't find a unique one.
  return &messages_[found_index];
}

void TestSink::AddFilter(Listener* filter) {
  filter_list_.AddObserver(filter);
}

void TestSink::RemoveFilter(Listener* filter) {
  filter_list_.RemoveObserver(filter);
}

#if defined(OS_POSIX) && !defined(OS_NACL)

int TestSink::GetClientFileDescriptor() const {
  NOTREACHED();
  return -1;
}

base::ScopedFD TestSink::TakeClientFileDescriptor() {
  NOTREACHED();
  return base::ScopedFD();
}

#endif  // defined(OS_POSIX) && !defined(OS_NACL)

}  // namespace IPC
