// Copyright (c) 2009 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 "brillo/glib/object.h"

#include <gtest/gtest.h>

#include <algorithm>
#include <cstring>
#include <iterator>
#include <string>

using brillo::glib::ScopedPtrArray;
using brillo::glib::ScopedError;
using brillo::glib::Retrieve;
using brillo::glib::Value;
using brillo::Resetter;

namespace {  // NOLINT

template <typename T>
void SetRetrieveTest(const T& x) {
  Value tmp(x);
  T result;
  EXPECT_TRUE(Retrieve(tmp, &result));
  EXPECT_EQ(result, x);
}

void ModifyValue(Value* x) {
  *x = 1.0 / 1231415926.0;   // An unlikely value
}

template <typename T, typename O>
void MutableRegularTestValue(const T& x, O modify) {
  Value tmp(x);
  Value y = tmp;  // copy-construction
  T result;
  EXPECT_TRUE(Retrieve(y, &result));
  EXPECT_EQ(result, x);
  modify(&y);
  LOG(INFO) << "Warning Expected.";
  EXPECT_TRUE(!(Retrieve(y, &result) && result == x));
  y = tmp;  // assignment
  EXPECT_TRUE(Retrieve(y, &result));
  EXPECT_EQ(result, x);
  modify(&y);
  LOG(INFO) << "Warning Expected.";
  EXPECT_TRUE(!(Retrieve(y, &result) && result == x));
}

void OutArgument(int** x) {
  *x = new int(10);  // NOLINT
}

}  // namespace

TEST(ResetterTest, All) {
  std::unique_ptr<int> x;
  OutArgument(&Resetter(&x).lvalue());
  EXPECT_EQ(*x, 10);
}

TEST(RetrieveTest, Types) {
  SetRetrieveTest(std::string("Hello!"));
  SetRetrieveTest(static_cast<uint32_t>(10));
  SetRetrieveTest(10.5);
  SetRetrieveTest(true);
}

TEST(ValueTest, All) {
  Value x;  // default construction
  Value y = x;  // copy with default value
  x = y;  // assignment with default value
  Value z(1.5);
  x = z;  // assignment to default value
  MutableRegularTestValue(std::string("Hello!"), &ModifyValue);
}

TEST(ScopedErrorTest, All) {
  ScopedError a;  // default construction
  ScopedError b(::g_error_new(::g_quark_from_static_string("error"), -1,
                              ""));  // constructor
  ::GError* c = ::g_error_new(::g_quark_from_static_string("error"), -1,
                              "");
  ::GError* d = ::g_error_new(::g_quark_from_static_string("error"), -1,
                              "");
  a.reset(c);  // reset form 1
  (void)d;
}

TEST(ScopedPtrArrayTest, Construction) {
  const char item[] = "a string";
  char* a = static_cast<char*>(::g_malloc(sizeof(item)));
  std::strcpy(a, &item[0]);  // NOLINT

  ::GPtrArray* array = ::g_ptr_array_new();
  ::g_ptr_array_add(array, ::gpointer(a));

  ScopedPtrArray<const char*> x(array);
  EXPECT_EQ(x.size(), 1);
  EXPECT_EQ(x[0], a);  // indexing
}

TEST(ScopedPtrArrayTest, Reset) {
  const char item[] = "a string";
  char* a = static_cast<char*>(::g_malloc(sizeof(item)));
  std::strcpy(a, &item[0]);  // NOLINT

  ScopedPtrArray<const char*> x;  // default construction
  x.push_back(a);
  EXPECT_EQ(x.size(), 1);
  x.reset();
  EXPECT_EQ(x.size(), 0);

  char* b = static_cast<char*>(::g_malloc(sizeof(item)));
  std::strcpy(b, &item[0]);  // NOLINT

  ::GPtrArray* array = ::g_ptr_array_new();
  ::g_ptr_array_add(array, ::gpointer(b));

  x.reset(array);
  EXPECT_EQ(x.size(), 1);
}

TEST(ScopedPtrArrayTest, Iteration) {
  char* a[] = { static_cast<char*>(::g_malloc(1)),
      static_cast<char*>(::g_malloc(1)), static_cast<char*>(::g_malloc(1)) };

  ScopedPtrArray<const char*> x;
  std::copy(&a[0], &a[3], std::back_inserter(x));
  EXPECT_TRUE(std::equal(x.begin(), x.end(), &a[0]));
}

