// Copyright (c) 2011 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 <stdint.h>

#include <utility>

#include "base/win/scoped_variant.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace win {

namespace {

static const wchar_t kTestString1[] = L"Used to create BSTRs";
static const wchar_t kTestString2[] = L"Also used to create BSTRs";

void GiveMeAVariant(VARIANT* ret) {
  EXPECT_TRUE(ret != NULL);
  ret->vt = VT_BSTR;
  V_BSTR(ret) = ::SysAllocString(kTestString1);
}

// A dummy IDispatch implementation (if you can call it that).
// The class does nothing intelligent really.  Only increments a counter
// when AddRef is called and decrements it when Release is called.
class FakeComObject : public IDispatch {
 public:
  FakeComObject() : ref_(0) {
  }

  STDMETHOD_(DWORD, AddRef)() override {
    ref_++;
    return ref_;
  }

  STDMETHOD_(DWORD, Release)() override {
    ref_--;
    return ref_;
  }

  STDMETHOD(QueryInterface)(REFIID, void**) override { return E_NOTIMPL; }

  STDMETHOD(GetTypeInfoCount)(UINT*) override { return E_NOTIMPL; }

  STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**) override { return E_NOTIMPL; }

  STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, UINT, LCID, DISPID*) override {
    return E_NOTIMPL;
  }

  STDMETHOD(Invoke)(DISPID,
                    REFIID,
                    LCID,
                    WORD,
                    DISPPARAMS*,
                    VARIANT*,
                    EXCEPINFO*,
                    UINT*) override {
    return E_NOTIMPL;
  }

  // A way to check the internal reference count of the class.
  int ref_count() const {
    return ref_;
  }

 protected:
  int ref_;
};

}  // namespace

TEST(ScopedVariantTest, ScopedVariant) {
  ScopedVariant var;
  EXPECT_TRUE(var.type() == VT_EMPTY);
  // V_BSTR(var.ptr()) = NULL;  <- NOTE: Assignment like that is not supported.

  ScopedVariant var_bstr(L"VT_BSTR");
  EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr()));
  EXPECT_TRUE(V_BSTR(var_bstr.ptr()) != NULL);  // can't use EXPECT_NE for BSTR
  var_bstr.Reset();
  EXPECT_NE(VT_BSTR, V_VT(var_bstr.ptr()));
  var_bstr.Set(kTestString2);
  EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr()));

  VARIANT tmp = var_bstr.Release();
  EXPECT_EQ(VT_EMPTY, V_VT(var_bstr.ptr()));
  EXPECT_EQ(VT_BSTR, V_VT(&tmp));
  EXPECT_EQ(0, lstrcmp(V_BSTR(&tmp), kTestString2));

  var.Reset(tmp);
  EXPECT_EQ(VT_BSTR, V_VT(var.ptr()));
  EXPECT_EQ(0, lstrcmpW(V_BSTR(var.ptr()), kTestString2));

  var_bstr.Swap(var);
  EXPECT_EQ(VT_EMPTY, V_VT(var.ptr()));
  EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr()));
  EXPECT_EQ(0, lstrcmpW(V_BSTR(var_bstr.ptr()), kTestString2));
  var_bstr.Reset();

  // Test the Compare and Copy routines.
  GiveMeAVariant(var_bstr.Receive());
  ScopedVariant var_bstr2(V_BSTR(var_bstr.ptr()));
  EXPECT_EQ(0, var_bstr.Compare(var_bstr2));
  var_bstr2.Reset();
  EXPECT_NE(0, var_bstr.Compare(var_bstr2));
  var_bstr2.Reset(var_bstr.Copy());
  EXPECT_EQ(0, var_bstr.Compare(var_bstr2));
  var_bstr2.Reset();
  var_bstr2.Set(V_BSTR(var_bstr.ptr()));
  EXPECT_EQ(0, var_bstr.Compare(var_bstr2));
  var_bstr2.Reset();
  var_bstr.Reset();

  // Test for the SetDate setter.
  SYSTEMTIME sys_time;
  ::GetSystemTime(&sys_time);
  DATE date;
  ::SystemTimeToVariantTime(&sys_time, &date);
  var.Reset();
  var.SetDate(date);
  EXPECT_EQ(VT_DATE, var.type());
  EXPECT_EQ(date, V_DATE(var.ptr()));

  // Simple setter tests.  These do not require resetting the variant
  // after each test since the variant type is not "leakable" (i.e. doesn't
  // need to be freed explicitly).

  // We need static cast here since char defaults to int (!?).
  var.Set(static_cast<int8_t>('v'));
  EXPECT_EQ(VT_I1, var.type());
  EXPECT_EQ('v', V_I1(var.ptr()));

  var.Set(static_cast<short>(123));
  EXPECT_EQ(VT_I2, var.type());
  EXPECT_EQ(123, V_I2(var.ptr()));

  var.Set(static_cast<int32_t>(123));
  EXPECT_EQ(VT_I4, var.type());
  EXPECT_EQ(123, V_I4(var.ptr()));

  var.Set(static_cast<int64_t>(123));
  EXPECT_EQ(VT_I8, var.type());
  EXPECT_EQ(123, V_I8(var.ptr()));

  var.Set(static_cast<uint8_t>(123));
  EXPECT_EQ(VT_UI1, var.type());
  EXPECT_EQ(123u, V_UI1(var.ptr()));

  var.Set(static_cast<unsigned short>(123));
  EXPECT_EQ(VT_UI2, var.type());
  EXPECT_EQ(123u, V_UI2(var.ptr()));

  var.Set(static_cast<uint32_t>(123));
  EXPECT_EQ(VT_UI4, var.type());
  EXPECT_EQ(123u, V_UI4(var.ptr()));

  var.Set(static_cast<uint64_t>(123));
  EXPECT_EQ(VT_UI8, var.type());
  EXPECT_EQ(123u, V_UI8(var.ptr()));

  var.Set(123.123f);
  EXPECT_EQ(VT_R4, var.type());
  EXPECT_EQ(123.123f, V_R4(var.ptr()));

  var.Set(static_cast<double>(123.123));
  EXPECT_EQ(VT_R8, var.type());
  EXPECT_EQ(123.123, V_R8(var.ptr()));

  var.Set(true);
  EXPECT_EQ(VT_BOOL, var.type());
  EXPECT_EQ(VARIANT_TRUE, V_BOOL(var.ptr()));
  var.Set(false);
  EXPECT_EQ(VT_BOOL, var.type());
  EXPECT_EQ(VARIANT_FALSE, V_BOOL(var.ptr()));

  // Com interface tests

  var.Set(static_cast<IDispatch*>(NULL));
  EXPECT_EQ(VT_DISPATCH, var.type());
  EXPECT_EQ(NULL, V_DISPATCH(var.ptr()));
  var.Reset();

  var.Set(static_cast<IUnknown*>(NULL));
  EXPECT_EQ(VT_UNKNOWN, var.type());
  EXPECT_EQ(NULL, V_UNKNOWN(var.ptr()));
  var.Reset();

  FakeComObject faker;
  EXPECT_EQ(0, faker.ref_count());
  var.Set(static_cast<IDispatch*>(&faker));
  EXPECT_EQ(VT_DISPATCH, var.type());
  EXPECT_EQ(&faker, V_DISPATCH(var.ptr()));
  EXPECT_EQ(1, faker.ref_count());
  var.Reset();
  EXPECT_EQ(0, faker.ref_count());

  var.Set(static_cast<IUnknown*>(&faker));
  EXPECT_EQ(VT_UNKNOWN, var.type());
  EXPECT_EQ(&faker, V_UNKNOWN(var.ptr()));
  EXPECT_EQ(1, faker.ref_count());
  var.Reset();
  EXPECT_EQ(0, faker.ref_count());

  {
    ScopedVariant disp_var(&faker);
    EXPECT_EQ(VT_DISPATCH, disp_var.type());
    EXPECT_EQ(&faker, V_DISPATCH(disp_var.ptr()));
    EXPECT_EQ(1, faker.ref_count());
  }
  EXPECT_EQ(0, faker.ref_count());

  {
    ScopedVariant ref1(&faker);
    EXPECT_EQ(1, faker.ref_count());
    ScopedVariant ref2(std::move(ref1));
    EXPECT_EQ(1, faker.ref_count());
    ScopedVariant ref3;
    ref3 = std::move(ref2);
    EXPECT_EQ(1, faker.ref_count());
  }
  EXPECT_EQ(0, faker.ref_count());

  {
    ScopedVariant ref1(&faker);
    EXPECT_EQ(1, faker.ref_count());
    ScopedVariant ref2(static_cast<const VARIANT&>(ref1));
    EXPECT_EQ(2, faker.ref_count());
    ScopedVariant ref3;
    ref3 = static_cast<const VARIANT&>(ref2);
    EXPECT_EQ(3, faker.ref_count());
  }
  EXPECT_EQ(0, faker.ref_count());

  {
    ScopedVariant unk_var(static_cast<IUnknown*>(&faker));
    EXPECT_EQ(VT_UNKNOWN, unk_var.type());
    EXPECT_EQ(&faker, V_UNKNOWN(unk_var.ptr()));
    EXPECT_EQ(1, faker.ref_count());
  }
  EXPECT_EQ(0, faker.ref_count());

  VARIANT raw;
  raw.vt = VT_UNKNOWN;
  raw.punkVal = &faker;
  EXPECT_EQ(0, faker.ref_count());
  var.Set(raw);
  EXPECT_EQ(1, faker.ref_count());
  var.Reset();
  EXPECT_EQ(0, faker.ref_count());

  {
    ScopedVariant number(123);
    EXPECT_EQ(VT_I4, number.type());
    EXPECT_EQ(123, V_I4(number.ptr()));
  }

  // SAFEARRAY tests
  var.Set(static_cast<SAFEARRAY*>(NULL));
  EXPECT_EQ(VT_EMPTY, var.type());

  SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 100);
  ASSERT_TRUE(sa != NULL);

  var.Set(sa);
  EXPECT_TRUE(ScopedVariant::IsLeakableVarType(var.type()));
  EXPECT_EQ(VT_ARRAY | VT_UI1, var.type());
  EXPECT_EQ(sa, V_ARRAY(var.ptr()));
  // The array is destroyed in the destructor of var.
}

}  // namespace win
}  // namespace base
