// Copyright 2014 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 <algorithm>
#include <ostream>
#include <string>
#include <utility>

#include "mojo/public/cpp/system/macros.h"
#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {

template <>
struct TypeConverter<int32_t, sample::BarPtr> {
  static int32_t Convert(const sample::BarPtr& bar) {
    return static_cast<int32_t>(bar->alpha) << 16 |
           static_cast<int32_t>(bar->beta) << 8 |
           static_cast<int32_t>(bar->gamma);
  }
};

}  // namespace mojo

namespace sample {
namespace {

// Set this variable to true to print the message in hex.
bool g_dump_message_as_hex = false;

// Set this variable to true to print the message in human readable form.
bool g_dump_message_as_text = false;

// Make a sample |Foo|.
FooPtr MakeFoo() {
  mojo::String name("foopy");

  BarPtr bar(Bar::New());
  bar->alpha = 20;
  bar->beta = 40;
  bar->gamma = 60;
  bar->type = Bar::Type::VERTICAL;

  auto extra_bars = mojo::Array<BarPtr>::New(3);
  for (size_t i = 0; i < extra_bars.size(); ++i) {
    Bar::Type type = i % 2 == 0 ? Bar::Type::VERTICAL : Bar::Type::HORIZONTAL;
    BarPtr bar(Bar::New());
    uint8_t base = static_cast<uint8_t>(i * 100);
    bar->alpha = base;
    bar->beta = base + 20;
    bar->gamma = base + 40;
    bar->type = type;
    extra_bars[i] = bar.Pass();
  }

  auto data = mojo::Array<uint8_t>::New(10);
  for (size_t i = 0; i < data.size(); ++i)
    data[i] = static_cast<uint8_t>(data.size() - i);

  auto input_streams = mojo::Array<mojo::ScopedDataPipeConsumerHandle>::New(2);
  auto output_streams = mojo::Array<mojo::ScopedDataPipeProducerHandle>::New(2);
  for (size_t i = 0; i < input_streams.size(); ++i) {
    MojoCreateDataPipeOptions options;
    options.struct_size = sizeof(MojoCreateDataPipeOptions);
    options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
    options.element_num_bytes = 1;
    options.capacity_num_bytes = 1024;
    mojo::ScopedDataPipeProducerHandle producer;
    mojo::ScopedDataPipeConsumerHandle consumer;
    mojo::CreateDataPipe(&options, &producer, &consumer);
    input_streams[i] = consumer.Pass();
    output_streams[i] = producer.Pass();
  }

  auto array_of_array_of_bools = mojo::Array<mojo::Array<bool>>::New(2);
  for (size_t i = 0; i < 2; ++i) {
    auto array_of_bools = mojo::Array<bool>::New(2);
    for (size_t j = 0; j < 2; ++j)
      array_of_bools[j] = j;
    array_of_array_of_bools[i] = array_of_bools.Pass();
  }

  mojo::MessagePipe pipe;
  FooPtr foo(Foo::New());
  foo->name = name;
  foo->x = 1;
  foo->y = 2;
  foo->a = false;
  foo->b = true;
  foo->c = false;
  foo->bar = bar.Pass();
  foo->extra_bars = extra_bars.Pass();
  foo->data = data.Pass();
  foo->source = pipe.handle1.Pass();
  foo->input_streams = input_streams.Pass();
  foo->output_streams = output_streams.Pass();
  foo->array_of_array_of_bools = array_of_array_of_bools.Pass();

  return foo;
}

// Check that the given |Foo| is identical to the one made by |MakeFoo()|.
void CheckFoo(const Foo& foo) {
  const std::string kName("foopy");
  ASSERT_FALSE(foo.name.is_null());
  EXPECT_EQ(kName.size(), foo.name.size());
  for (size_t i = 0; i < std::min(kName.size(), foo.name.size()); i++) {
    // Test both |operator[]| and |at|.
    EXPECT_EQ(kName[i], foo.name.at(i)) << i;
    EXPECT_EQ(kName[i], foo.name[i]) << i;
  }
  EXPECT_EQ(kName, foo.name.get());

  EXPECT_EQ(1, foo.x);
  EXPECT_EQ(2, foo.y);
  EXPECT_FALSE(foo.a);
  EXPECT_TRUE(foo.b);
  EXPECT_FALSE(foo.c);

  EXPECT_EQ(20, foo.bar->alpha);
  EXPECT_EQ(40, foo.bar->beta);
  EXPECT_EQ(60, foo.bar->gamma);
  EXPECT_EQ(Bar::Type::VERTICAL, foo.bar->type);

  EXPECT_EQ(3u, foo.extra_bars.size());
  for (size_t i = 0; i < foo.extra_bars.size(); i++) {
    uint8_t base = static_cast<uint8_t>(i * 100);
    Bar::Type type = i % 2 == 0 ? Bar::Type::VERTICAL : Bar::Type::HORIZONTAL;
    EXPECT_EQ(base, foo.extra_bars[i]->alpha) << i;
    EXPECT_EQ(base + 20, foo.extra_bars[i]->beta) << i;
    EXPECT_EQ(base + 40, foo.extra_bars[i]->gamma) << i;
    EXPECT_EQ(type, foo.extra_bars[i]->type) << i;
  }

  EXPECT_EQ(10u, foo.data.size());
  for (size_t i = 0; i < foo.data.size(); ++i) {
    EXPECT_EQ(static_cast<uint8_t>(foo.data.size() - i), foo.data[i]) << i;
  }

  EXPECT_FALSE(foo.input_streams.is_null());
  EXPECT_EQ(2u, foo.input_streams.size());

  EXPECT_FALSE(foo.output_streams.is_null());
  EXPECT_EQ(2u, foo.output_streams.size());

  EXPECT_EQ(2u, foo.array_of_array_of_bools.size());
  for (size_t i = 0; i < foo.array_of_array_of_bools.size(); ++i) {
    EXPECT_EQ(2u, foo.array_of_array_of_bools[i].size());
    for (size_t j = 0; j < foo.array_of_array_of_bools[i].size(); ++j) {
      EXPECT_EQ(bool(j), foo.array_of_array_of_bools[i][j]);
    }
  }
}

void PrintSpacer(int depth) {
  for (int i = 0; i < depth; ++i)
    std::cout << "   ";
}

void Print(int depth, const char* name, bool value) {
  PrintSpacer(depth);
  std::cout << name << ": " << (value ? "true" : "false") << std::endl;
}

void Print(int depth, const char* name, int32_t value) {
  PrintSpacer(depth);
  std::cout << name << ": " << value << std::endl;
}

void Print(int depth, const char* name, uint8_t value) {
  PrintSpacer(depth);
  std::cout << name << ": " << uint32_t(value) << std::endl;
}

template <typename H>
void Print(int depth,
           const char* name,
           const mojo::ScopedHandleBase<H>& value) {
  PrintSpacer(depth);
  std::cout << name << ": 0x" << std::hex << value.get().value() << std::endl;
}

void Print(int depth, const char* name, const mojo::String& str) {
  PrintSpacer(depth);
  std::cout << name << ": \"" << str.get() << "\"" << std::endl;
}

void Print(int depth, const char* name, const BarPtr& bar) {
  PrintSpacer(depth);
  std::cout << name << ":" << std::endl;
  if (!bar.is_null()) {
    ++depth;
    Print(depth, "alpha", bar->alpha);
    Print(depth, "beta", bar->beta);
    Print(depth, "gamma", bar->gamma);
    Print(depth, "packed", bar.To<int32_t>());
    --depth;
  }
}

template <typename T>
void Print(int depth, const char* name, const mojo::Array<T>& array) {
  PrintSpacer(depth);
  std::cout << name << ":" << std::endl;
  if (!array.is_null()) {
    ++depth;
    for (size_t i = 0; i < array.size(); ++i) {
      std::stringstream buf;
      buf << i;
      Print(depth, buf.str().data(), array.at(i));
    }
    --depth;
  }
}

void Print(int depth, const char* name, const FooPtr& foo) {
  PrintSpacer(depth);
  std::cout << name << ":" << std::endl;
  if (!foo.is_null()) {
    ++depth;
    Print(depth, "name", foo->name);
    Print(depth, "x", foo->x);
    Print(depth, "y", foo->y);
    Print(depth, "a", foo->a);
    Print(depth, "b", foo->b);
    Print(depth, "c", foo->c);
    Print(depth, "bar", foo->bar);
    Print(depth, "extra_bars", foo->extra_bars);
    Print(depth, "data", foo->data);
    Print(depth, "source", foo->source);
    Print(depth, "input_streams", foo->input_streams);
    Print(depth, "output_streams", foo->output_streams);
    Print(depth, "array_of_array_of_bools", foo->array_of_array_of_bools);
    --depth;
  }
}

void DumpHex(const uint8_t* bytes, uint32_t num_bytes) {
  for (uint32_t i = 0; i < num_bytes; ++i) {
    std::cout << std::setw(2) << std::setfill('0') << std::hex
              << uint32_t(bytes[i]);

    if (i % 16 == 15) {
      std::cout << std::endl;
      continue;
    }

    if (i % 2 == 1)
      std::cout << " ";
    if (i % 8 == 7)
      std::cout << " ";
  }
}

class ServiceImpl : public Service {
 public:
  void Frobinate(FooPtr foo,
                 BazOptions baz,
                 mojo::InterfaceHandle<Port> port,
                 const Service::FrobinateCallback& callback) override {
    // Users code goes here to handle the incoming Frobinate message.

    // We mainly check that we're given the expected arguments.
    EXPECT_FALSE(foo.is_null());
    if (!foo.is_null())
      CheckFoo(*foo);
    EXPECT_EQ(Service::BazOptions::EXTRA, baz);

    if (g_dump_message_as_text) {
      // Also dump the Foo structure and all of its members.
      std::cout << "Frobinate:" << std::endl;
      int depth = 1;
      Print(depth, "foo", foo);
      Print(depth, "baz", static_cast<int32_t>(baz));
      auto portptr = PortPtr::Create(std::move(port));
      Print(depth, "port", portptr.get());
    }
    callback.Run(5);
  }

  void GetPort(mojo::InterfaceRequest<Port> port_request) override {}
};

class ServiceProxyImpl : public ServiceProxy {
 public:
  explicit ServiceProxyImpl(mojo::MessageReceiverWithResponder* receiver)
      : ServiceProxy(receiver) {}
};

class SimpleMessageReceiver : public mojo::MessageReceiverWithResponder {
 public:
  bool Accept(mojo::Message* message) override {
    // Imagine some IPC happened here.

    if (g_dump_message_as_hex) {
      DumpHex(reinterpret_cast<const uint8_t*>(message->data()),
              message->data_num_bytes());
    }

    // In the receiving process, an implementation of ServiceStub is known to
    // the system. It receives the incoming message.
    ServiceImpl impl;

    ServiceStub stub;
    stub.set_sink(&impl);
    return stub.Accept(message);
  }

  bool AcceptWithResponder(mojo::Message* message,
                           mojo::MessageReceiver* responder) override {
    return false;
  }
};

TEST(BindingsSampleTest, Basic) {
  SimpleMessageReceiver receiver;

  // User has a proxy to a Service somehow.
  Service* service = new ServiceProxyImpl(&receiver);

  // User constructs a message to send.

  // Notice that it doesn't matter in what order the structs / arrays are
  // allocated. Here, the various members of Foo are allocated before Foo is
  // allocated.

  FooPtr foo = MakeFoo();
  CheckFoo(*foo);

  PortPtr port;
  service->Frobinate(foo.Pass(), Service::BazOptions::EXTRA, std::move(port),
                     Service::FrobinateCallback());

  delete service;
}

TEST(BindingsSampleTest, DefaultValues) {
  DefaultsTestPtr defaults(DefaultsTest::New());
  EXPECT_EQ(-12, defaults->a0);
  EXPECT_EQ(kTwelve, defaults->a1);
  EXPECT_EQ(1234, defaults->a2);
  EXPECT_EQ(34567U, defaults->a3);
  EXPECT_EQ(123456, defaults->a4);
  EXPECT_EQ(3456789012U, defaults->a5);
  EXPECT_EQ(-111111111111LL, defaults->a6);
  EXPECT_EQ(9999999999999999999ULL, defaults->a7);
  EXPECT_EQ(0x12345, defaults->a8);
  EXPECT_EQ(-0x12345, defaults->a9);
  EXPECT_EQ(1234, defaults->a10);
  EXPECT_TRUE(defaults->a11);
  EXPECT_FALSE(defaults->a12);
  EXPECT_FLOAT_EQ(123.25f, defaults->a13);
  EXPECT_DOUBLE_EQ(1234567890.123, defaults->a14);
  EXPECT_DOUBLE_EQ(1E10, defaults->a15);
  EXPECT_DOUBLE_EQ(-1.2E+20, defaults->a16);
  EXPECT_DOUBLE_EQ(1.23E-20, defaults->a17);
  EXPECT_TRUE(defaults->a18.is_null());
  EXPECT_TRUE(defaults->a19.is_null());
  EXPECT_EQ(Bar::Type::BOTH, defaults->a20);
  EXPECT_TRUE(defaults->a21.is_null());
  ASSERT_FALSE(defaults->a22.is_null());
  EXPECT_EQ(imported::Shape::RECTANGLE, defaults->a22->shape);
  EXPECT_EQ(imported::Color::BLACK, defaults->a22->color);
  EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, defaults->a23);
  EXPECT_EQ(0x123456789, defaults->a24);
  EXPECT_EQ(-0x123456789, defaults->a25);
}

}  // namespace
}  // namespace sample
