// Copyright 2019 The Fuchsia 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 <fuchsia/inspect/cpp/fidl.h>
#include <lib/component/cpp/expose.h>
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace {

using component::Metric;
using component::Object;
using component::Property;
using testing::UnorderedElementsAre;

MATCHER_P2(StringProperty, name, value, "") {
  return arg.value.is_str() && arg.key == name && arg.value.str() == value;
}

MATCHER_P2(VectorProperty, name, value, "") {
  return arg.value.is_bytes() && arg.key == name && arg.value.bytes() == value;
}

MATCHER_P2(UIntMetric, name, value, "") {
  return arg.key == name && arg.value.is_uint_value() &&
         arg.value.uint_value() == static_cast<uint64_t>(value);
}

MATCHER_P2(IntMetric, name, value, "") {
  return arg.key == name && arg.value.is_int_value() &&
         arg.value.int_value() == static_cast<int64_t>(value);
}

MATCHER_P2(DoubleMetric, name, value, "") {
  return arg.key == name && arg.value.is_double_value() &&
         arg.value.double_value() == static_cast<double>(value);
}

TEST(Property, StringValue) {
  Property a("test");

  EXPECT_THAT(a.ToFidl("key"), StringProperty("key", "test"));
  a.Set("test2");
  EXPECT_THAT(a.ToFidl("key"), StringProperty("key", "test2"));
}

TEST(Property, VectorValue) {
  Property::ByteVector test_vector;
  test_vector.push_back('\0');
  test_vector.push_back('\10');

  Property a(test_vector);

  EXPECT_THAT(a.ToFidl("key"), VectorProperty("key", test_vector));
  test_vector.push_back('a');
  a.Set(test_vector);
  EXPECT_THAT(a.ToFidl("key"), VectorProperty("key", test_vector));
}

TEST(Property, StringCallback) {
  Property a([] { return std::string("test"); });

  // Check callback is called.
  EXPECT_THAT(a.ToFidl("key"), StringProperty("key", "test"));

  // Set to new callback, cancelling token. New value should be present.
  a.Set([] { return std::string("test2"); });
  EXPECT_THAT(a.ToFidl("key"), StringProperty("key", "test2"));
}

TEST(Property, VectorCallback) {
  Property a([] { return Property::ByteVector(2, 'a'); });

  // Check callback is called.
  EXPECT_THAT(a.ToFidl("key"),
              VectorProperty("key", Property::ByteVector(2, 'a')));

  // Set to new callback, cancelling token. New value should be present.
  a.Set([] { return Property::ByteVector(2, 'b'); });
  EXPECT_THAT(a.ToFidl("key"),
              VectorProperty("key", Property::ByteVector(2, 'b')));
}

TEST(Metric, SetValue) {
  Metric a;

  EXPECT_THAT(a.ToFidl("key"), IntMetric("key", 0));

  a.SetInt(-10);
  EXPECT_THAT(a.ToFidl("key"), IntMetric("key", -10));

  a.SetUInt(1000);
  EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 1000));

  a.SetDouble(1.25);
  EXPECT_THAT(a.ToFidl("key"), DoubleMetric("key", 1.25));
}

TEST(Metric, Arithmetic) {
  Metric a;

  EXPECT_THAT(a.ToFidl("key"), IntMetric("key", 0));

  a.Sub(10);
  EXPECT_THAT(a.ToFidl("key"), IntMetric("key", -10));
  a.Sub(1.5);
  EXPECT_THAT(a.ToFidl("key"), IntMetric("key", -11));

  a.SetUInt(0);
  a.Add(1);
  EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 1));
  // Check that overflowing works properly.
  // Subtracting below 0 should wrap around.
  // Adding and subtracting by a double should also wrap.
  a.Sub(2);
  EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 0xFFFFFFFFFFFFFFFF));
  a.Add(2.12);
  EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 1));
  a.Sub(2.12);
  EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 0xFFFFFFFFFFFFFFFF));
  a.Add(-1);
  EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 0xFFFFFFFFFFFFFFFE));

  a.SetDouble(1.25);
  a.Add(0.5);
  EXPECT_THAT(a.ToFidl("key"), DoubleMetric("key", 1.75));
  a.Sub(1);
  EXPECT_THAT(a.ToFidl("key"), DoubleMetric("key", 0.75));
}

TEST(Metric, ValueCallback) {
  Metric a = component::CallbackMetric(
      [](Metric* out_metric) { out_metric->SetInt(10); });

  // Check callback is called.
  EXPECT_THAT(a.ToFidl("key"), IntMetric("key", 10));

  // Set to new callback, cancelling token. New value should be present.
  a.SetCallback([](Metric* out_metric) { out_metric->SetInt(11); });
  EXPECT_THAT(a.ToFidl("key"), IntMetric("key", 11));
}

TEST(Object, Name) {
  fbl::RefPtr<Object> object = fbl::MakeRefCounted<Object>("test");
  EXPECT_STREQ("test", object->name().c_str());
}

TEST(Object, ReadData) {
  fbl::RefPtr<Object> object = fbl::MakeRefCounted<Object>("test");
  object->SetProperty("property", component::Property("value"));
  object->SetMetric("int metric", component::IntMetric(-10));
  object->SetMetric("uint metric", component::UIntMetric(0xFF));
  object->SetMetric("double metric", component::DoubleMetric(0.25));

  fuchsia::inspect::Object obj;
  object->ReadData(
      [&obj](fuchsia::inspect::Object val) { obj = std::move(val); });
  EXPECT_STREQ("test", obj.name.c_str());
  EXPECT_THAT(*obj.properties,
              UnorderedElementsAre(StringProperty("property", "value")));
  EXPECT_THAT(*obj.metrics,
              UnorderedElementsAre(IntMetric("int metric", -10),
                                   UIntMetric("uint metric", 0xFF),
                                   DoubleMetric("double metric", 0.25)));
}

component::Object::StringOutputVector ListChildren(fbl::RefPtr<Object> object) {
  component::Object::StringOutputVector ret;
  object->ListChildren([&ret](component::Object::StringOutputVector val) {
    ret = std::move(val);
  });
  return ret;
}

TEST(Object, SetTakeChild) {
  fbl::RefPtr<Object> object = fbl::MakeRefCounted<Object>("test");
  component::Object::StringOutputVector children_list;

  object->SetChild(fbl::MakeRefCounted<Object>("child1"));
  children_list = ListChildren(object);
  EXPECT_THAT(*children_list, UnorderedElementsAre(fidl::StringPtr("child1")));

  auto child = object->TakeChild("child1");
  children_list = ListChildren(object);
  EXPECT_STREQ("child1", child->name().c_str());
  EXPECT_THAT(*children_list, UnorderedElementsAre());
}

TEST(Object, ChildrenCallback) {
  fbl::RefPtr<Object> object = fbl::MakeRefCounted<Object>("test");
  component::Object::StringOutputVector children_list;

  object->SetChild(fbl::MakeRefCounted<Object>("concrete1"));
  object->SetChild(fbl::MakeRefCounted<Object>("concrete2"));

  children_list = ListChildren(object);
  EXPECT_THAT(*children_list,
              UnorderedElementsAre(fidl::StringPtr("concrete1"),
                                   fidl::StringPtr("concrete2")));

  // Set the callback and ensure it is merged with the concrete objects.
  object->SetChildrenCallback([](component::Object::ObjectVector* out) {
    out->emplace_back(fbl::MakeRefCounted<Object>("dynamic1"));
    out->emplace_back(fbl::MakeRefCounted<Object>("dynamic2"));
    out->emplace_back(fbl::MakeRefCounted<Object>("dynamic3"));
  });
  children_list = ListChildren(object);
  EXPECT_THAT(*children_list,
              UnorderedElementsAre(
                  fidl::StringPtr("concrete1"), fidl::StringPtr("concrete2"),
                  fidl::StringPtr("dynamic1"), fidl::StringPtr("dynamic2"),
                  fidl::StringPtr("dynamic3")));
}

}  // namespace
