// 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"
#include "matchers.h"

namespace {

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

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"), ByteVectorProperty("key", test_vector));
  test_vector.push_back('a');
  a.Set(test_vector);
  EXPECT_THAT(a.ToFidl("key"), ByteVectorProperty("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"),
              ByteVectorProperty("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"),
              ByteVectorProperty("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
