// 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 "mojo/public/cpp/environment/environment.h"
#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;

  mojo::Array<BarPtr> extra_bars(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();
  }

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

  mojo::Array<mojo::ScopedDataPipeConsumerHandle> input_streams(2);
  mojo::Array<mojo::ScopedDataPipeProducerHandle> output_streams(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();
  }

  mojo::Array<mojo::Array<bool>> array_of_array_of_bools(2);
  for (size_t i = 0; i < 2; ++i) {
    mojo::Array<bool> array_of_bools(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.Pass();
}

// 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, PortPtr port) 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(BAZ_OPTIONS_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", baz);
      Print(depth, "port", port.get());
    }
  }

  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;
  }
};

class BindingsSampleTest : public testing::Test {
 public:
  BindingsSampleTest() {}
  ~BindingsSampleTest() override {}

 private:
  mojo::Environment env_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(BindingsSampleTest);
};

TEST_F(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::BAZ_OPTIONS_EXTRA, port.Pass());

  delete service;
}

TEST_F(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
