// 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 overlaping 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
