// 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 "ui/gfx/break_list.h"

#include <stddef.h>

#include "base/cxx17_backports.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/range/range.h"

namespace gfx {

class BreakListTest : public testing::Test {};

TEST_F(BreakListTest, SetValue) {
  // Check the default values applied to new instances.
  BreakList<bool> style_breaks(false);
  EXPECT_TRUE(style_breaks.EqualsValueForTesting(false));
  style_breaks.SetValue(true);
  EXPECT_TRUE(style_breaks.EqualsValueForTesting(true));

  // Ensure that setting values works correctly.
  BreakList<SkColor> color_breaks(SK_ColorRED);
  EXPECT_TRUE(color_breaks.EqualsValueForTesting(SK_ColorRED));
  color_breaks.SetValue(SK_ColorBLACK);
  EXPECT_TRUE(color_breaks.EqualsValueForTesting(SK_ColorBLACK));
}

TEST_F(BreakListTest, ApplyValue) {
  BreakList<bool> breaks(false);
  const size_t max = 99;
  breaks.SetMax(max);

  // Ensure ApplyValue is a no-op on invalid and empty ranges.
  breaks.ApplyValue(true, Range::InvalidRange());
  EXPECT_TRUE(breaks.EqualsValueForTesting(false));
  for (size_t i = 0; i < 3; ++i) {
    breaks.ApplyValue(true, Range(i, i));
    EXPECT_TRUE(breaks.EqualsValueForTesting(false));
  }

  // Apply a value to a valid range, check breaks; repeating should be no-op.
  std::vector<std::pair<size_t, bool> > expected;
  expected.push_back(std::pair<size_t, bool>(0, false));
  expected.push_back(std::pair<size_t, bool>(2, true));
  expected.push_back(std::pair<size_t, bool>(3, false));
  for (size_t i = 0; i < 2; ++i) {
    breaks.ApplyValue(true, Range(2, 3));
    EXPECT_TRUE(breaks.EqualsForTesting(expected));
  }

  // Ensure setting a value overrides the ranged value.
  breaks.SetValue(true);
  EXPECT_TRUE(breaks.EqualsValueForTesting(true));

  // Ensure applying a value over [0, |max|) is the same as setting a value.
  breaks.ApplyValue(false, Range(0, max));
  EXPECT_TRUE(breaks.EqualsValueForTesting(false));

  // Ensure applying a value that is already applied has no effect.
  breaks.ApplyValue(false, Range(0, 2));
  breaks.ApplyValue(false, Range(3, 6));
  breaks.ApplyValue(false, Range(7, max));
  EXPECT_TRUE(breaks.EqualsValueForTesting(false));

  // Ensure applying an identical neighboring value merges the ranges.
  breaks.ApplyValue(true, Range(0, 3));
  breaks.ApplyValue(true, Range(3, 6));
  breaks.ApplyValue(true, Range(6, max));
  EXPECT_TRUE(breaks.EqualsValueForTesting(true));

  // Ensure applying a value with the same range overrides the ranged value.
  breaks.ApplyValue(false, Range(2, 3));
  breaks.ApplyValue(true, Range(2, 3));
  EXPECT_TRUE(breaks.EqualsValueForTesting(true));

  // Ensure applying a value with a containing range overrides contained values.
  breaks.ApplyValue(false, Range(0, 1));
  breaks.ApplyValue(false, Range(2, 3));
  breaks.ApplyValue(true, Range(0, 3));
  EXPECT_TRUE(breaks.EqualsValueForTesting(true));
  breaks.ApplyValue(false, Range(4, 5));
  breaks.ApplyValue(false, Range(6, 7));
  breaks.ApplyValue(false, Range(8, 9));
  breaks.ApplyValue(true, Range(4, 9));
  EXPECT_TRUE(breaks.EqualsValueForTesting(true));

  // Ensure applying various overlapping values yields the intended results.
  breaks.ApplyValue(false, Range(1, 4));
  breaks.ApplyValue(false, Range(5, 8));
  breaks.ApplyValue(true, Range(0, 2));
  breaks.ApplyValue(true, Range(3, 6));
  breaks.ApplyValue(true, Range(7, max));
  std::vector<std::pair<size_t, bool> > overlap;
  overlap.push_back(std::pair<size_t, bool>(0, true));
  overlap.push_back(std::pair<size_t, bool>(2, false));
  overlap.push_back(std::pair<size_t, bool>(3, true));
  overlap.push_back(std::pair<size_t, bool>(6, false));
  overlap.push_back(std::pair<size_t, bool>(7, true));
  EXPECT_TRUE(breaks.EqualsForTesting(overlap));
}

TEST_F(BreakListTest, SetMax) {
  // Ensure values adjust to accommodate max position changes.
  BreakList<bool> breaks(false);
  breaks.SetMax(9);
  breaks.ApplyValue(true, Range(0, 2));
  breaks.ApplyValue(true, Range(3, 6));
  breaks.ApplyValue(true, Range(7, 9));

  std::vector<std::pair<size_t, bool> > expected;
  expected.push_back(std::pair<size_t, bool>(0, true));
  expected.push_back(std::pair<size_t, bool>(2, false));
  expected.push_back(std::pair<size_t, bool>(3, true));
  expected.push_back(std::pair<size_t, bool>(6, false));
  expected.push_back(std::pair<size_t, bool>(7, true));
  EXPECT_TRUE(breaks.EqualsForTesting(expected));

  // Setting a smaller max should remove any corresponding breaks.
  breaks.SetMax(7);
  expected.resize(4);
  EXPECT_TRUE(breaks.EqualsForTesting(expected));
  breaks.SetMax(4);
  expected.resize(3);
  EXPECT_TRUE(breaks.EqualsForTesting(expected));
  breaks.SetMax(4);
  EXPECT_TRUE(breaks.EqualsForTesting(expected));

  // Setting a larger max should not change any breaks.
  breaks.SetMax(50);
  EXPECT_TRUE(breaks.EqualsForTesting(expected));
}

TEST_F(BreakListTest, GetBreakAndRange) {
  BreakList<bool> breaks(false);
  breaks.SetMax(8);
  breaks.ApplyValue(true, Range(1, 2));
  breaks.ApplyValue(true, Range(4, 6));

  struct {
    size_t position;
    size_t break_index;
    Range range;
  } cases[] = {
    { 0, 0, Range(0, 1) },
    { 1, 1, Range(1, 2) },
    { 2, 2, Range(2, 4) },
    { 3, 2, Range(2, 4) },
    { 4, 3, Range(4, 6) },
    { 5, 3, Range(4, 6) },
    { 6, 4, Range(6, 8) },
    { 7, 4, Range(6, 8) },
    // Positions at or beyond the max simply return the last break and range.
    { 8, 4, Range(6, 8) },
    { 9, 4, Range(6, 8) },
  };

  for (size_t i = 0; i < base::size(cases); ++i) {
    BreakList<bool>::const_iterator it = breaks.GetBreak(cases[i].position);
    EXPECT_EQ(breaks.breaks()[cases[i].break_index], *it);
    EXPECT_EQ(breaks.GetRange(it), cases[i].range);
  }
}

}  // namespace gfx
