/*
 * Copyright (c) 2013, Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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/TimeRanges.h>

using namespace WebCore;

namespace TestWebKitAPI {

static std::string ToString(const TimeRanges& ranges)
{
    std::stringstream ss;
    ss << "{";
    for (unsigned i = 0; i < ranges.length(); ++i)
        ss << " [" << ranges.start(i).releaseReturnValue() << "," << ranges.end(i).releaseReturnValue() << ")";
    ss << " }";

    return ss.str();
}

#define ASSERT_RANGE(expected, range) EXPECT_EQ(expected, ToString(*range))

TEST(TimeRanges, Empty)
{
    ASSERT_RANGE("{ }", TimeRanges::create().ptr());
}

TEST(TimeRanges, SingleRange)
{
    ASSERT_RANGE("{ [1,2) }", TimeRanges::create(1, 2).ptr());
}

TEST(TimeRanges, AddOrder)
{
    RefPtr<TimeRanges> rangeA = TimeRanges::create();
    RefPtr<TimeRanges> rangeB = TimeRanges::create();

    rangeA->add(0, 2);
    rangeA->add(3, 4);
    rangeA->add(5, 100);

    std::string expected = "{ [0,2) [3,4) [5,100) }";
    ASSERT_RANGE(expected, rangeA);

    // Add the values in rangeA to rangeB in reverse order.
    for (int i = rangeA->length() - 1; i >= 0; --i)
        rangeB->add(rangeA->start(i).releaseReturnValue(), rangeA->end(i).releaseReturnValue());

    ASSERT_RANGE(expected, rangeB);
}

TEST(TimeRanges, OverlappingAdds)
{
    RefPtr<TimeRanges> ranges = TimeRanges::create();

    ranges->add(0, 2);
    ranges->add(10, 11);
    ASSERT_RANGE("{ [0,2) [10,11) }", ranges);

    ranges->add(0, 2);
    ASSERT_RANGE("{ [0,2) [10,11) }", ranges);

    ranges->add(2, 3);
    ASSERT_RANGE("{ [0,3) [10,11) }", ranges);

    ranges->add(2, 6);
    ASSERT_RANGE("{ [0,6) [10,11) }", ranges);

    ranges->add(9, 10);
    ASSERT_RANGE("{ [0,6) [9,11) }", ranges);

    ranges->add(8, 10);
    ASSERT_RANGE("{ [0,6) [8,11) }", ranges);

    ranges->add(-1, 7);
    ASSERT_RANGE("{ [-1,7) [8,11) }", ranges);

    ranges->add(6, 9);
    ASSERT_RANGE("{ [-1,11) }", ranges);
}

TEST(TimeRanges, IntersectWith_Self)
{
    RefPtr<TimeRanges> ranges = TimeRanges::create(0, 2);

    ASSERT_RANGE("{ [0,2) }", ranges);

    ranges->intersectWith(*ranges.get());

    ASSERT_RANGE("{ [0,2) }", ranges);
}

TEST(TimeRanges, IntersectWith_IdenticalRange)
{
    RefPtr<TimeRanges> rangesA = TimeRanges::create(0, 2);
    RefPtr<TimeRanges> rangesB = rangesA->copy();

    ASSERT_RANGE("{ [0,2) }", rangesA);
    ASSERT_RANGE("{ [0,2) }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ [0,2) }", rangesA);
    ASSERT_RANGE("{ [0,2) }", rangesB);
}

TEST(TimeRanges, IntersectWith_Empty)
{
    RefPtr<TimeRanges> rangesA = TimeRanges::create(0, 2);
    RefPtr<TimeRanges> rangesB = TimeRanges::create();

    ASSERT_RANGE("{ [0,2) }", rangesA);
    ASSERT_RANGE("{ }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ }", rangesA);
    ASSERT_RANGE("{ }", rangesB);
}

TEST(TimeRanges, IntersectWith_DisjointRanges1)
{
    
    RefPtr<TimeRanges> rangesA = TimeRanges::create();
    RefPtr<TimeRanges> rangesB = TimeRanges::create();

    rangesA->add(0, 1);
    rangesA->add(4, 5);

    rangesB->add(2, 3);
    rangesB->add(6, 7);

    ASSERT_RANGE("{ [0,1) [4,5) }", rangesA);
    ASSERT_RANGE("{ [2,3) [6,7) }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ }", rangesA);
    ASSERT_RANGE("{ [2,3) [6,7) }", rangesB);
}

TEST(TimeRanges, IntersectWith_DisjointRanges2)
{
    RefPtr<TimeRanges> rangesA = TimeRanges::create();
    RefPtr<TimeRanges> rangesB = TimeRanges::create();

    rangesA->add(0, 1);
    rangesA->add(4, 5);

    rangesB->add(1, 4);
    rangesB->add(5, 7);

    ASSERT_RANGE("{ [0,1) [4,5) }", rangesA);
    ASSERT_RANGE("{ [1,4) [5,7) }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ }", rangesA);
    ASSERT_RANGE("{ [1,4) [5,7) }", rangesB);
}

TEST(TimeRanges, IntersectWith_CompleteOverlap1)
{
    RefPtr<TimeRanges> rangesA = TimeRanges::create();
    RefPtr<TimeRanges> rangesB = TimeRanges::create();

    rangesA->add(1, 3);
    rangesA->add(4, 5);
    rangesA->add(6, 9);

    rangesB->add(0, 10);

    ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
    ASSERT_RANGE("{ [0,10) }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
    ASSERT_RANGE("{ [0,10) }", rangesB);
}

TEST(TimeRanges, IntersectWith_CompleteOverlap2)
{
    RefPtr<TimeRanges> rangesA = TimeRanges::create();
    RefPtr<TimeRanges> rangesB = TimeRanges::create();

    rangesA->add(1, 3);
    rangesA->add(4, 5);
    rangesA->add(6, 9);

    rangesB->add(1, 9);

    ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
    ASSERT_RANGE("{ [1,9) }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
    ASSERT_RANGE("{ [1,9) }", rangesB);
}

TEST(TimeRanges, IntersectWith_Gaps1)
{
    RefPtr<TimeRanges> rangesA = TimeRanges::create();
    RefPtr<TimeRanges> rangesB = TimeRanges::create();

    rangesA->add(0, 2);
    rangesA->add(4, 6);

    rangesB->add(1, 5);

    ASSERT_RANGE("{ [0,2) [4,6) }", rangesA);
    ASSERT_RANGE("{ [1,5) }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ [1,2) [4,5) }", rangesA);
    ASSERT_RANGE("{ [1,5) }", rangesB);
}

TEST(TimeRanges, IntersectWith_Gaps2)
{
    RefPtr<TimeRanges> rangesA = TimeRanges::create();
    RefPtr<TimeRanges> rangesB = TimeRanges::create();

    rangesA->add(0, 2);
    rangesA->add(4, 6);
    rangesA->add(8, 10);

    rangesB->add(1, 9);

    ASSERT_RANGE("{ [0,2) [4,6) [8,10) }", rangesA);
    ASSERT_RANGE("{ [1,9) }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ [1,2) [4,6) [8,9) }", rangesA);
    ASSERT_RANGE("{ [1,9) }", rangesB);
}

TEST(TimeRanges, IntersectWith_Gaps3)
{
    RefPtr<TimeRanges> rangesA = TimeRanges::create();
    RefPtr<TimeRanges> rangesB = TimeRanges::create();

    rangesA->add(0, 2);
    rangesA->add(4, 7);
    rangesA->add(8, 10);

    rangesB->add(1, 5);
    rangesB->add(6, 9);

    ASSERT_RANGE("{ [0,2) [4,7) [8,10) }", rangesA);
    ASSERT_RANGE("{ [1,5) [6,9) }", rangesB);

    rangesA->intersectWith(*rangesB.get());

    ASSERT_RANGE("{ [1,2) [4,5) [6,7) [8,9) }", rangesA);
    ASSERT_RANGE("{ [1,5) [6,9) }", rangesB);
}

}

