// Copyright (c) 2012 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 "cobalt/media/base/ranges.h"

#include <sstream>

#include "base/strings/string_piece.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace media {

// Human-readable output operator, for debugging/testability.
template <class T>
std::ostream& operator<<(std::ostream& os, const Ranges<T>& r) {
  os << "{ ";
  for (size_t i = 0; i < r.size(); ++i)
    os << "[" << r.start(i) << "," << r.end(i) << ") ";
  os << "}";
  return os;
}

// Helper method for asserting stringified form of |r| matches expectation.
template <class T>
static void ExpectRanges(const Ranges<T>& r,
                         const base::StringPiece& expected_string) {
  std::stringstream ss;
  ss << r;
  ASSERT_EQ(ss.str(), expected_string);
}

#define ASSERT_RANGES(ranges, expectation) \
  ASSERT_NO_FATAL_FAILURE(ExpectRanges(ranges, expectation));

TEST(RangesTest, SimpleTests) {
  Ranges<int> r;
  ASSERT_EQ(r.size(), 0u) << r;
  ASSERT_EQ(r.Add(0, 1), 1u) << r;
  ASSERT_EQ(r.size(), 1u) << r;
  ASSERT_RANGES(r, "{ [0,1) }");
  ASSERT_EQ(r.Add(2, 3), 2u) << r;
  ASSERT_RANGES(r, "{ [0,1) [2,3) }");
  ASSERT_EQ(r.Add(1, 2), 1u) << r;
  ASSERT_RANGES(r, "{ [0,3) }");
  ASSERT_EQ(r.Add(1, 4), 1u) << r;
  ASSERT_RANGES(r, "{ [0,4) }");
  ASSERT_EQ(r.Add(7, 9), 2u) << r;
  ASSERT_EQ(r.Add(5, 6), 3u) << r;
  ASSERT_RANGES(r, "{ [0,4) [5,6) [7,9) }");
  ASSERT_EQ(r.Add(6, 7), 2u) << r;
  ASSERT_RANGES(r, "{ [0,4) [5,9) }");
}

TEST(RangesTest, ExtendRange) {
  Ranges<double> r;
  ASSERT_EQ(r.Add(0, 1), 1u) << r;
  ASSERT_EQ(r.Add(0.5, 1.5), 1u) << r;
  ASSERT_RANGES(r, "{ [0,1.5) }");

  r.clear();
  ASSERT_EQ(r.Add(0, 1), 1u) << r;
  ASSERT_EQ(r.Add(-0.5, 0.5), 1u) << r;
  ASSERT_RANGES(r, "{ [-0.5,1) }");

  r.clear();
  ASSERT_EQ(r.Add(0, 1), 1u) << r;
  ASSERT_EQ(r.Add(2, 3), 2u) << r;
  ASSERT_EQ(r.Add(4, 5), 3u) << r;
  ASSERT_EQ(r.Add(0.5, 1.5), 3u) << r;
  ASSERT_RANGES(r, "{ [0,1.5) [2,3) [4,5) }");

  r.clear();
  ASSERT_EQ(r.Add(0, 1), 1u) << r;
  ASSERT_EQ(r.Add(2, 3), 2u) << r;
  ASSERT_EQ(r.Add(4, 5), 3u) << r;
  ASSERT_EQ(r.Add(1.5, 2.5), 3u) << r;
  ASSERT_RANGES(r, "{ [0,1) [1.5,3) [4,5) }");
}

TEST(RangesTest, CoalesceRanges) {
  Ranges<double> r;
  ASSERT_EQ(r.Add(0, 1), 1u) << r;
  ASSERT_EQ(r.Add(2, 3), 2u) << r;
  ASSERT_EQ(r.Add(4, 5), 3u) << r;
  ASSERT_EQ(r.Add(0.5, 2.5), 2u) << r;
  ASSERT_RANGES(r, "{ [0,3) [4,5) }");

  r.clear();
  ASSERT_EQ(r.Add(0, 1), 1u) << r;
  ASSERT_EQ(r.Add(2, 3), 2u) << r;
  ASSERT_EQ(r.Add(4, 5), 3u) << r;
  ASSERT_EQ(r.Add(0.5, 4.5), 1u) << r;
  ASSERT_RANGES(r, "{ [0,5) }");

  r.clear();
  ASSERT_EQ(r.Add(0, 1), 1u) << r;
  ASSERT_EQ(r.Add(1, 2), 1u) << r;
  ASSERT_RANGES(r, "{ [0,2) }");
}

TEST(RangesTest, IntersectionWith) {
  Ranges<int> a;
  Ranges<int> b;

  ASSERT_EQ(a.Add(0, 1), 1u) << a;
  ASSERT_EQ(a.Add(4, 7), 2u) << a;
  ASSERT_EQ(a.Add(10, 12), 3u) << a;

  // Test intersections with an empty range.
  ASSERT_RANGES(a, "{ [0,1) [4,7) [10,12) }");
  ASSERT_RANGES(b, "{ }");
  ASSERT_RANGES(a.IntersectionWith(b), "{ }");
  ASSERT_RANGES(b.IntersectionWith(a), "{ }");

  // Test intersections with a completely overlapping range.
  ASSERT_EQ(b.Add(-1, 13), 1u) << b;
  ASSERT_RANGES(a, "{ [0,1) [4,7) [10,12) }");
  ASSERT_RANGES(b, "{ [-1,13) }");
  ASSERT_RANGES(a.IntersectionWith(b), "{ [0,1) [4,7) [10,12) }");
  ASSERT_RANGES(b.IntersectionWith(a), "{ [0,1) [4,7) [10,12) }");

  // Test intersections with a disjoint ranges.
  b.clear();
  ASSERT_EQ(b.Add(1, 4), 1u) << b;
  ASSERT_EQ(b.Add(8, 9), 2u) << b;
  ASSERT_RANGES(a, "{ [0,1) [4,7) [10,12) }");
  ASSERT_RANGES(b, "{ [1,4) [8,9) }");
  ASSERT_RANGES(a.IntersectionWith(b), "{ }");
  ASSERT_RANGES(b.IntersectionWith(a), "{ }");

  // Test intersections with partially overlapping ranges.
  b.clear();
  ASSERT_EQ(b.Add(0, 3), 1u) << b;
  ASSERT_EQ(b.Add(5, 11), 2u) << b;
  ASSERT_RANGES(a, "{ [0,1) [4,7) [10,12) }");
  ASSERT_RANGES(b, "{ [0,3) [5,11) }");
  ASSERT_RANGES(a.IntersectionWith(b), "{ [0,1) [5,7) [10,11) }");
  ASSERT_RANGES(b.IntersectionWith(a), "{ [0,1) [5,7) [10,11) }");

  // Test intersection with a range that starts at the beginning of the
  // first range and ends at the end of the last range.
  b.clear();
  ASSERT_EQ(b.Add(0, 12), 1u) << b;
  ASSERT_RANGES(a, "{ [0,1) [4,7) [10,12) }");
  ASSERT_RANGES(b, "{ [0,12) }");
  ASSERT_RANGES(a.IntersectionWith(b), "{ [0,1) [4,7) [10,12) }");
  ASSERT_RANGES(b.IntersectionWith(a), "{ [0,1) [4,7) [10,12) }");
}

}  // namespace media
}  // namespace cobalt
