/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements a test for  CHIP core library reference counted object.
 *
 */

#include <array>
#include <cinttypes>
#include <cstdint>
#include <cstring>

#include <lib/core/Optional.h>
#include <lib/support/Span.h>

#include <gtest/gtest.h>

using namespace chip;

struct Count
{
    Count(int i) : m(i) { ++created; }
    ~Count() { ++destroyed; }

    Count(const Count & o) : m(o.m) { ++created; }
    Count & operator=(const Count &) = default;

    Count(Count && o) : m(o.m) { ++created; }
    Count & operator=(Count &&) = default;

    bool operator==(const Count & o) const { return m == o.m; }

    int m;

    static void ResetCounter()
    {
        created   = 0;
        destroyed = 0;
    }

    static int created;
    static int destroyed;
};

struct CountMovable : public Count
{
public:
    CountMovable(int i) : Count(i) {}

    CountMovable(const CountMovable & o)           = delete;
    CountMovable & operator=(const CountMovable &) = delete;

    CountMovable(CountMovable && o)           = default;
    CountMovable & operator=(CountMovable &&) = default;
};

int Count::created;
int Count::destroyed;

TEST(TestOptional, TestBasic)
{
    // Set up our test Count objects, which will mess with counts, before we reset the
    // counts.
    Count c100(100), c101(101), c102(102);

    Count::ResetCounter();

    {
        auto testOptional = Optional<Count>::Value(100);
        EXPECT_TRUE(Count::created == 1 && Count::destroyed == 0);
        EXPECT_TRUE(testOptional.HasValue() && testOptional.Value().m == 100);
        EXPECT_EQ(testOptional, c100);
        EXPECT_NE(testOptional, c101);
        EXPECT_NE(testOptional, c102);

        testOptional.ClearValue();
        EXPECT_TRUE(Count::created == 1 && Count::destroyed == 1);
        EXPECT_FALSE(testOptional.HasValue());
        EXPECT_NE(testOptional, c100);
        EXPECT_NE(testOptional, c101);
        EXPECT_NE(testOptional, c102);

        testOptional.SetValue(Count(101));
        EXPECT_TRUE(Count::created == 3 && Count::destroyed == 2);
        EXPECT_TRUE(testOptional.HasValue() && testOptional.Value().m == 101);
        EXPECT_NE(testOptional, c100);
        EXPECT_EQ(testOptional, c101);
        EXPECT_NE(testOptional, c102);

        testOptional.Emplace(102);
        EXPECT_TRUE(Count::created == 4 && Count::destroyed == 3);
        EXPECT_TRUE(testOptional.HasValue() && testOptional.Value().m == 102);
        EXPECT_NE(testOptional, c100);
        EXPECT_NE(testOptional, c101);
        EXPECT_EQ(testOptional, c102);
    }

    // Our test Count objects are still in scope here.
    EXPECT_TRUE(Count::created == 4 && Count::destroyed == 4);
}

TEST(TestOptional, TestMake)
{
    Count::ResetCounter();

    {
        auto testOptional = MakeOptional<Count>(200);
        EXPECT_TRUE(Count::created == 1 && Count::destroyed == 0);
        EXPECT_TRUE(testOptional.HasValue() && testOptional.Value().m == 200);
    }

    EXPECT_TRUE(Count::created == 1 && Count::destroyed == 1);
}

TEST(TestOptional, TestCopy)
{
    Count::ResetCounter();

    {
        auto testSrc = Optional<Count>::Value(300);
        EXPECT_TRUE(Count::created == 1 && Count::destroyed == 0);
        EXPECT_TRUE(testSrc.HasValue() && testSrc.Value().m == 300);

        {
            Optional<Count> testDst(testSrc);
            EXPECT_TRUE(Count::created == 2 && Count::destroyed == 0);
            EXPECT_TRUE(testDst.HasValue() && testDst.Value().m == 300);
        }
        EXPECT_TRUE(Count::created == 2 && Count::destroyed == 1);

        {
            Optional<Count> testDst;
            EXPECT_TRUE(Count::created == 2 && Count::destroyed == 1);
            EXPECT_FALSE(testDst.HasValue());

            testDst = testSrc;
            EXPECT_TRUE(Count::created == 3 && Count::destroyed == 1);
            EXPECT_TRUE(testDst.HasValue() && testDst.Value().m == 300);
        }
        EXPECT_TRUE(Count::created == 3 && Count::destroyed == 2);
    }
    EXPECT_TRUE(Count::created == 3 && Count::destroyed == 3);
}

TEST(TestOptional, TestMove)
{
    Count::ResetCounter();

    {
        auto testSrc = MakeOptional<CountMovable>(400);
        Optional<CountMovable> testDst(std::move(testSrc));
        EXPECT_TRUE(Count::created == 2 && Count::destroyed == 1);
        EXPECT_TRUE(testDst.HasValue() && testDst.Value().m == 400);
    }
    EXPECT_TRUE(Count::created == 2 && Count::destroyed == 2);

    {
        Optional<CountMovable> testDst;
        EXPECT_TRUE(Count::created == 2 && Count::destroyed == 2);
        EXPECT_FALSE(testDst.HasValue());

        auto testSrc = MakeOptional<CountMovable>(401);
        testDst      = std::move(testSrc);
        EXPECT_TRUE(Count::created == 4 && Count::destroyed == 3);
        EXPECT_TRUE(testDst.HasValue() && testDst.Value().m == 401);
    }
    EXPECT_TRUE(Count::created == 4 && Count::destroyed == 4);
}

TEST(TestOptional, TestConversion)
{
    // FixedSpan is implicitly convertible from std::array
    using WidgetView    = FixedSpan<const bool, 10>;
    using WidgetStorage = std::array<bool, 10>;

    auto optStorage                   = MakeOptional<WidgetStorage>();
    auto const & constOptStorage      = optStorage;
    auto optOtherStorage              = MakeOptional<WidgetStorage>();
    auto const & constOptOtherStorage = optOtherStorage;

    EXPECT_TRUE(optStorage.HasValue());
    EXPECT_TRUE(optOtherStorage.HasValue());

    Optional<WidgetView> optView(constOptStorage);
    EXPECT_TRUE(optView.HasValue());
    EXPECT_EQ(&optView.Value()[0], &optStorage.Value()[0]);

    optView = optOtherStorage;
    optView = constOptOtherStorage;
    EXPECT_TRUE(optView.HasValue());
    EXPECT_EQ(&optView.Value()[0], &optOtherStorage.Value()[0]);

    struct ExplicitBool
    {
        explicit ExplicitBool(bool) {}
    };
    Optional<ExplicitBool> e(Optional<bool>(true)); // OK, explicitly constructing the optional

    // The following should not compile
    // e = Optional<bool>(false); // relies on implicit conversion
}
