// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/strings/split.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "common/strings/range.h"
#include "common/util/range.h"

namespace verible {
namespace {

using ::testing::ElementsAre;

static void AcceptFunctionChar(std::function<absl::string_view(char)> func) {}
static void AcceptFunctionStringView(
    std::function<absl::string_view(absl::string_view)> func) {}

// This tests that StringSpliterator can be passed to a std::function.
TEST(StringSpliteratorTest, CompileTimeAsFunction) {
  StringSpliterator splitter("a,b,c");
  AcceptFunctionChar(splitter);
  AcceptFunctionStringView(splitter);
}

TEST(StringSpliteratorTest, EmptyOriginal) {
  constexpr absl::string_view empty("");
  StringSpliterator splitter(empty);
  EXPECT_TRUE(splitter);
  EXPECT_TRUE(BoundsEqual(splitter.Remainder(), empty));
  const auto token = splitter(",");
  EXPECT_EQ(token, "");
  EXPECT_TRUE(BoundsEqual(splitter.Remainder(), empty));
  EXPECT_TRUE(BoundsEqual(token, empty));
  EXPECT_FALSE(splitter);  // reached end
  EXPECT_EQ(splitter(","), "");
  EXPECT_TRUE(BoundsEqual(splitter.Remainder(), empty));
}

TEST(StringSpliteratorTest, MyGodItsFullOfStars) {
  constexpr absl::string_view stars("***");
  const auto gen = MakeStringSpliterator(stars, '*');  // char delimiter
  EXPECT_TRUE(BoundsEqual(gen(), stars.substr(0, 0)));
  EXPECT_TRUE(BoundsEqual(gen(), stars.substr(1, 0)));
  EXPECT_TRUE(BoundsEqual(gen(), stars.substr(2, 0)));
  EXPECT_TRUE(BoundsEqual(gen(), stars.substr(3, 0)));
}

TEST(StringSpliteratorTest, StringDelimiter) {
  constexpr absl::string_view stars("xxx");
  const auto gen = MakeStringSpliterator(stars, "x");  // string delimiter
  EXPECT_TRUE(BoundsEqual(gen(), stars.substr(0, 0)));
  EXPECT_TRUE(BoundsEqual(gen(), stars.substr(1, 0)));
  EXPECT_TRUE(BoundsEqual(gen(), stars.substr(2, 0)));
  EXPECT_TRUE(BoundsEqual(gen(), stars.substr(3, 0)));
}

TEST(StringSpliteratorTest, StarsAndStripes) {
  constexpr absl::string_view space("==*===*=*====");
  StringSpliterator splitter(space);
  EXPECT_TRUE(splitter);
  EXPECT_TRUE(BoundsEqual(splitter.Remainder(), space));

  absl::string_view token = splitter('*');
  EXPECT_TRUE(splitter);
  EXPECT_TRUE(BoundsEqual(token, space.substr(0, 2)))
      << " got \"" << token << '"';
  EXPECT_TRUE(BoundsEqual(splitter.Remainder(), space.substr(3)));

  token = splitter('*');
  EXPECT_TRUE(splitter);
  EXPECT_TRUE(BoundsEqual(token, space.substr(3, 3)))
      << " got \"" << token << '"';
  EXPECT_TRUE(BoundsEqual(splitter.Remainder(), space.substr(7)));

  token = splitter('*');
  EXPECT_TRUE(splitter);
  EXPECT_TRUE(BoundsEqual(token, space.substr(7, 1)))
      << " got \"" << token << '"';
  EXPECT_TRUE(BoundsEqual(splitter.Remainder(), space.substr(9)));

  token = splitter('*');
  EXPECT_FALSE(splitter);  // this was the last token
  EXPECT_TRUE(BoundsEqual(token, space.substr(9, 4)))
      << " got \"" << token << '"';
  EXPECT_TRUE(BoundsEqual(splitter.Remainder(), space.substr(space.length())));
}

TEST(StringSpliteratorTest, InSpaceNoOneCanHearYouScream) {
  constexpr absl::string_view space("  *   * *    ");
  const auto gen = MakeStringSpliterator(space, '*');  // char delimiter
  // expect to match the spaces between the stars
  EXPECT_TRUE(BoundsEqual(gen(), space.substr(0, 2)));
  EXPECT_TRUE(BoundsEqual(gen(), space.substr(3, 3)));
  EXPECT_TRUE(BoundsEqual(gen(), space.substr(7, 1)));
  EXPECT_TRUE(BoundsEqual(gen(), space.substr(9, 4)));
}

TEST(StringSpliteratorTest, CommaBabyCommaOverBaby) {
  constexpr absl::string_view csv_row("abcd,,efg,hi");
  const auto gen = MakeStringSpliterator(csv_row, ",");  // string delimiter
  // expect to match the spaces between the stars
  EXPECT_TRUE(BoundsEqual(gen(), csv_row.substr(0, 4)));
  EXPECT_TRUE(BoundsEqual(gen(), csv_row.substr(5, 0)));
  EXPECT_TRUE(BoundsEqual(gen(), csv_row.substr(6, 3)));
  EXPECT_TRUE(BoundsEqual(gen(), csv_row.substr(10, 2)));
}

using IntPair = std::pair<int, int>;

// For testing purposes, directly compare the substring indices,
// which is a stronger check than string contents comparison.
static std::vector<IntPair> SplitLinesToOffsets(absl::string_view text) {
  std::vector<IntPair> offsets;
  for (const auto& line : SplitLines(text)) {
    offsets.push_back(SubstringOffsets(line, text));
  }
  return offsets;
}

TEST(SplitLinesTest, Empty) {
  constexpr absl::string_view text("");
  const auto lines = SplitLines(text);
  EXPECT_TRUE(lines.empty());
}

TEST(SplitLinesTest, OneSpace) {
  constexpr absl::string_view text(" ");
  EXPECT_THAT(SplitLines(text), ElementsAre(" "));
  EXPECT_THAT(SplitLinesToOffsets(text), ElementsAre(IntPair(0, 1)));
}

TEST(SplitLinesTest, OneBlankLine) {
  constexpr absl::string_view text("\n");
  EXPECT_THAT(SplitLines(text), ElementsAre(""));
  EXPECT_THAT(SplitLinesToOffsets(text), ElementsAre(IntPair(0, 0)));
}

TEST(SplitLinesTest, BlankLines) {
  constexpr absl::string_view text("\n\n\n");
  EXPECT_THAT(SplitLines(text), ElementsAre("", "", ""));
  EXPECT_THAT(SplitLinesToOffsets(text),
              ElementsAre(IntPair(0, 0), IntPair(1, 1), IntPair(2, 2)));
}

TEST(SplitLinesTest, NonBlankLines) {
  constexpr absl::string_view text("a\nbc\ndef\n");
  EXPECT_THAT(SplitLines(text), ElementsAre("a", "bc", "def"));
  EXPECT_THAT(SplitLinesToOffsets(text),
              ElementsAre(IntPair(0, 1), IntPair(2, 4), IntPair(5, 8)));
}

TEST(SplitLinesTest, NonBlankLinesUnterminated) {
  constexpr absl::string_view text("abc\nde\nf");  // no \n at the end
  EXPECT_THAT(SplitLines(text), ElementsAre("abc", "de", "f"));
  EXPECT_THAT(SplitLinesToOffsets(text),
              ElementsAre(IntPair(0, 3), IntPair(4, 6), IntPair(7, 8)));
}

}  // namespace
}  // namespace verible
