// 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 "p2p/common/struct_serializer.h"

#include "p2p/common/testutil.h"

#include <fcntl.h>
#include <glib.h>
#include <unistd.h>

#include <string>

#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>

using p2p::testutil::RunGMainLoopMaxIterations;
using std::string;

namespace {

struct TestStruct {
  int a, b, c;
};

bool operator==(const TestStruct& left, const TestStruct& right) {
  return left.a == right.a && left.b == right.b && left.c == right.c;
}

class TestStructCalls {
 public:
  TestStructCalls() : num_calls(0) {}

  static void CountCalls(const TestStruct& data, void* user_data) {
    TestStructCalls* calls = reinterpret_cast<TestStructCalls*>(user_data);
    calls->num_calls++;
    calls->last_call = data;
  }

  TestStruct last_call;
  int num_calls;
};

bool SetupPipes(int fds[2]) {
  if (pipe(fds) != 0) return false;

  // Set the reading end as non-blocking.
  int flags = fcntl(fds[0], F_GETFL, 0);
  fcntl(fds[0], F_SETFL, flags | O_NONBLOCK);

  return true;
}

}  // namespace

namespace p2p {

namespace util {

TEST(StructSerializer, SimpleWriteTest) {
  int fds[2];
  ASSERT_TRUE(SetupPipes(fds));

  const TestStruct sample = {1, 2, 3};
  char buffer[sizeof(TestStruct)];

  EXPECT_TRUE(StructSerializerWrite<TestStruct>(fds[1], sample));
  EXPECT_EQ(sizeof(TestStruct), read(fds[0], buffer, sizeof(TestStruct)));
  EXPECT_EQ(0, memcmp(&sample, buffer, sizeof(TestStruct)));

  close(fds[0]);
  close(fds[1]);
}

TEST(StructSerializer, WatchSeveralMessages) {
  int fds[2];
  ASSERT_TRUE(SetupPipes(fds));

  TestStructCalls calls = TestStructCalls();
  StructSerializerWatcher<TestStruct> watch(
      fds[0], TestStructCalls::CountCalls, &calls);

  TestStruct sample = {1, 2, 3};
  EXPECT_TRUE(StructSerializerWrite<TestStruct>(fds[1], sample));
  sample.b = 4;
  EXPECT_TRUE(StructSerializerWrite<TestStruct>(fds[1], sample));
  sample.c = 5;
  EXPECT_TRUE(StructSerializerWrite<TestStruct>(fds[1], sample));

  // Run the main loop until all the events are dispatched.
  while (g_main_context_iteration(NULL, FALSE)) {}

  EXPECT_EQ(calls.num_calls, 3);
  const TestStruct result = {1, 4, 5};
  EXPECT_EQ(calls.last_call, result);

  close(fds[0]);
  close(fds[1]);
}

TEST(StructSerializer, WatchNoMessages) {
  int fds[2];
  ASSERT_TRUE(SetupPipes(fds));

  TestStructCalls calls = TestStructCalls();
  StructSerializerWatcher<TestStruct> watch(
      fds[0], TestStructCalls::CountCalls, &calls);

  // Close the write end.
  close(fds[1]);

  // Run the main loop until all the events are dispatched.
  int iterations = RunGMainLoopMaxIterations(10);

  // No call is received but the callback is called once due to the hangup.
  EXPECT_EQ(iterations, 1);
  EXPECT_EQ(calls.num_calls, 0);
  close(fds[0]);
}

TEST(StructSerializer, WatchPartialMessage) {
  int fds[2];
  ASSERT_TRUE(SetupPipes(fds));

  TestStructCalls calls = TestStructCalls();
  StructSerializerWatcher<TestStruct> watch(
      fds[0], TestStructCalls::CountCalls, &calls);

  // Write a partial message.
  int x = -1;
  ASSERT_EQ(sizeof(int), write(fds[1], &x, sizeof(x)));

  // Run the main loop until all the events are dispatched.
  int iterations = RunGMainLoopMaxIterations(10);
  EXPECT_EQ(iterations, 1);

  // Write the second part of the message.
  x = 2;
  ASSERT_EQ(sizeof(int), write(fds[1], &x, sizeof(x)));
  x = 4;
  ASSERT_EQ(sizeof(int), write(fds[1], &x, sizeof(x)));

  iterations = RunGMainLoopMaxIterations(10);
  EXPECT_EQ(iterations, 1);

  EXPECT_EQ(calls.num_calls, 1);
  const TestStruct result = {-1, 2, 4};
  EXPECT_EQ(calls.last_call, result);
  close(fds[0]);
  close(fds[1]);
}

}  // namespace util

}  // namespace p2p
