/*
 * Copyright (C) 2014 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include <WebCore/CalculationValue.h>
#include <wtf/RefPtr.h>

namespace WTF {
class TextStream;
};

namespace TestWebKitAPI {

static unsigned deletionCount;

class CalculationDeletionTestNode : public WebCore::CalcExpressionNode {
    WTF_MAKE_FAST_ALLOCATED;
public:
    virtual ~CalculationDeletionTestNode()
    {
        ++deletionCount;
    }

    float evaluate(float) const override { return 0; }
    bool operator==(const CalcExpressionNode&) const override { ASSERT_NOT_REACHED(); return false; }

private:
    void dump(WTF::TextStream&) const override { };
};

static Ref<WebCore::CalculationValue> createTestValue()
{
    auto node = makeUnique<CalculationDeletionTestNode>();
    return WebCore::CalculationValue::create(WTFMove(node), WebCore::ValueRangeAll);
}

TEST(CalculationValue, LengthConstruction)
{
    RefPtr<WebCore::CalculationValue> value = createTestValue();

    EXPECT_EQ(1U, value->refCount());

    {
        WebCore::Length length(*value);
        EXPECT_EQ(2U, value->refCount());
    }

    EXPECT_EQ(1U, value->refCount());

    {
        WebCore::Length lengthA(*value);
        EXPECT_EQ(2U, value->refCount());
        WebCore::Length lengthB(lengthA);
        EXPECT_EQ(2U, value->refCount());
    }

    EXPECT_EQ(1U, value->refCount());

    {
        WebCore::Length lengthC(*value);
        EXPECT_EQ(2U, value->refCount());
        WebCore::Length lengthD(WTFMove(lengthC));
        EXPECT_EQ(2U, value->refCount());
    }

    EXPECT_EQ(1U, value->refCount());

    EXPECT_EQ(0U, deletionCount);
    value = nullptr;
    EXPECT_EQ(1U, deletionCount);
    deletionCount = 0;
}

TEST(CalculationValue, LengthConstructionReleasedValue)
{
    RefPtr<WebCore::CalculationValue> value = createTestValue();

    EXPECT_EQ(1U, value->refCount());

    {
        auto* rawValue = value.get();
        WebCore::Length length(value.releaseNonNull());
        EXPECT_EQ(1U, rawValue->refCount());

        EXPECT_EQ(0U, deletionCount);
    }

    EXPECT_EQ(1U, deletionCount);
    deletionCount = 0;

    value = createTestValue();

    {
        auto* rawValue = value.get();
        WebCore::Length lengthA(value.releaseNonNull());
        EXPECT_EQ(1U, rawValue->refCount());
        WebCore::Length lengthB(lengthA);
        EXPECT_EQ(1U, rawValue->refCount());

        EXPECT_EQ(0U, deletionCount);
    }

    EXPECT_EQ(1U, deletionCount);
    deletionCount = 0;

    value = createTestValue();

    {
        auto* rawValue = value.get();
        WebCore::Length lengthC(value.releaseNonNull());
        EXPECT_EQ(1U, rawValue->refCount());
        WebCore::Length lengthD(WTFMove(lengthC));
        EXPECT_EQ(1U, rawValue->refCount());

        EXPECT_EQ(0U, deletionCount);
    }

    EXPECT_EQ(1U, deletionCount);
    deletionCount = 0;
}

TEST(CalculationValue, LengthAssignment)
{
    RefPtr<WebCore::CalculationValue> value = createTestValue();

    EXPECT_EQ(1U, value->refCount());

    {
        WebCore::Length lengthA(*value);
        EXPECT_EQ(2U, value->refCount());
        WebCore::Length lengthB;
        lengthB = lengthA;
        EXPECT_EQ(2U, value->refCount());
    }

    EXPECT_EQ(1U, value->refCount());

    {
        WebCore::Length lengthC(*value);
        EXPECT_EQ(2U, value->refCount());
        WebCore::Length lengthD;
        lengthD = WTFMove(lengthC);
        EXPECT_EQ(2U, value->refCount());
    }

    EXPECT_EQ(1U, value->refCount());

    EXPECT_EQ(0U, deletionCount);
    value = nullptr;
    EXPECT_EQ(1U, deletionCount);
    deletionCount = 0;

    value = createTestValue();
    RefPtr<WebCore::CalculationValue> value2 = createTestValue();

    EXPECT_EQ(1U, value->refCount());
    EXPECT_EQ(1U, value2->refCount());

    {
        WebCore::Length lengthE(*value);
        EXPECT_EQ(2U, value->refCount());
        WebCore::Length lengthF(*value2);
        EXPECT_EQ(2U, value2->refCount());
        lengthE = lengthF;
        EXPECT_EQ(1U, value->refCount());
        EXPECT_EQ(2U, value2->refCount());
    }

    EXPECT_EQ(1U, value->refCount());
    EXPECT_EQ(1U, value2->refCount());

    {
        WebCore::Length lengthG(*value);
        EXPECT_EQ(2U, value->refCount());
        WebCore::Length lengthH(*value2);
        EXPECT_EQ(2U, value2->refCount());
        lengthG = WTFMove(lengthH);
        EXPECT_EQ(1U, value->refCount());
        EXPECT_EQ(2U, value2->refCount());
    }

    EXPECT_EQ(0U, deletionCount);
    value = nullptr;
    EXPECT_EQ(1U, deletionCount);
    value2 = nullptr;
    EXPECT_EQ(2U, deletionCount);
    deletionCount = 0;
}

TEST(CalculationValue, LengthAssignmentReleasedValue)
{
    RefPtr<WebCore::CalculationValue> value = createTestValue();

    {
        auto* rawValue = value.get();
        WebCore::Length lengthA(value.releaseNonNull());
        EXPECT_EQ(1U, rawValue->refCount());
        WebCore::Length lengthB;
        lengthB = lengthA;
        EXPECT_EQ(1U, rawValue->refCount());

        EXPECT_EQ(0U, deletionCount);
    }

    EXPECT_EQ(1U, deletionCount);
    deletionCount = 0;

    value = createTestValue();

    {
        auto* rawValue = value.get();
        WebCore::Length lengthC(value.releaseNonNull());
        EXPECT_EQ(1U, rawValue->refCount());
        WebCore::Length lengthD;
        lengthD = WTFMove(lengthC);
        EXPECT_EQ(1U, rawValue->refCount());

        EXPECT_EQ(0U, deletionCount);
    }

    EXPECT_EQ(1U, deletionCount);
    deletionCount = 0;

    value = createTestValue();
    RefPtr<WebCore::CalculationValue> value2 = createTestValue();

    EXPECT_EQ(1U, value->refCount());
    EXPECT_EQ(1U, value2->refCount());

    {
        auto* rawValue = value.get();
        WebCore::Length lengthE(value.releaseNonNull());
        EXPECT_EQ(1U, rawValue->refCount());
        auto* rawValue2 = value2.get();
        WebCore::Length lengthF(value2.releaseNonNull());
        EXPECT_EQ(1U, rawValue2->refCount());

        lengthE = lengthF;
        EXPECT_EQ(1U, deletionCount);
        EXPECT_EQ(1U, rawValue2->refCount());
    }

    EXPECT_EQ(2U, deletionCount);
    deletionCount = 0;

    value = createTestValue();
    value2 = createTestValue();

    EXPECT_EQ(1U, value->refCount());
    EXPECT_EQ(1U, value2->refCount());

    {
        auto* rawValue = value.get();
        WebCore::Length lengthG(value.releaseNonNull());
        EXPECT_EQ(1U, rawValue->refCount());
        auto* rawValue2 = value2.get();
        WebCore::Length lengthH(value2.releaseNonNull());
        EXPECT_EQ(1U, rawValue2->refCount());

        lengthG = WTFMove(lengthH);
        EXPECT_EQ(1U, deletionCount);
        EXPECT_EQ(1U, rawValue2->refCount());
    }

    EXPECT_EQ(2U, deletionCount);
    deletionCount = 0;
}

}
