// Copyright 2007-2008 the V8 project authors. 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 <stdlib.h>

#include "src/v8.h"

#include "src/debug/liveedit.h"
#include "src/objects-inl.h"
#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {

// Anonymous namespace.
namespace {

class StringCompareInput : public Comparator::Input {
 public:
  StringCompareInput(const char* s1, const char* s2) : s1_(s1), s2_(s2) {
  }
  int GetLength1() {
    return StrLength(s1_);
  }
  int GetLength2() {
    return StrLength(s2_);
  }
  bool Equals(int index1, int index2) {
    return s1_[index1] == s2_[index2];
  }

 private:
  const char* s1_;
  const char* s2_;
};


class DiffChunkStruct : public ZoneObject {
 public:
  DiffChunkStruct(int pos1_param, int pos2_param,
                  int len1_param, int len2_param)
      : pos1(pos1_param), pos2(pos2_param),
        len1(len1_param), len2(len2_param), next(NULL) {}
  int pos1;
  int pos2;
  int len1;
  int len2;
  DiffChunkStruct* next;
};


class ListDiffOutputWriter : public Comparator::Output {
 public:
  explicit ListDiffOutputWriter(DiffChunkStruct** next_chunk_pointer,
                                Zone* zone)
      : next_chunk_pointer_(next_chunk_pointer), zone_(zone) {
    (*next_chunk_pointer_) = NULL;
  }
  void AddChunk(int pos1, int pos2, int len1, int len2) {
    current_chunk_ = new(zone_) DiffChunkStruct(pos1, pos2, len1, len2);
    (*next_chunk_pointer_) = current_chunk_;
    next_chunk_pointer_ = &current_chunk_->next;
  }
 private:
  DiffChunkStruct** next_chunk_pointer_;
  DiffChunkStruct* current_chunk_;
  Zone* zone_;
};


void CompareStringsOneWay(const char* s1, const char* s2,
                          int expected_diff_parameter = -1) {
  StringCompareInput input(s1, s2);

  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);

  DiffChunkStruct* first_chunk;
  ListDiffOutputWriter writer(&first_chunk, &zone);

  Comparator::CalculateDifference(&input, &writer);

  int len1 = StrLength(s1);
  int len2 = StrLength(s2);

  int pos1 = 0;
  int pos2 = 0;

  int diff_parameter = 0;

  for (DiffChunkStruct* chunk = first_chunk;
      chunk != NULL;
      chunk = chunk->next) {
    int diff_pos1 = chunk->pos1;
    int similar_part_length = diff_pos1 - pos1;
    int diff_pos2 = pos2 + similar_part_length;

    CHECK_EQ(diff_pos2, chunk->pos2);

    for (int j = 0; j < similar_part_length; j++) {
      CHECK(pos1 + j < len1);
      CHECK(pos2 + j < len2);
      CHECK_EQ(s1[pos1 + j], s2[pos2 + j]);
    }
    diff_parameter += chunk->len1 + chunk->len2;
    pos1 = diff_pos1 + chunk->len1;
    pos2 = diff_pos2 + chunk->len2;
  }
  {
    // After last chunk.
    int similar_part_length = len1 - pos1;
    CHECK_EQ(similar_part_length, len2 - pos2);
    USE(len2);
    for (int j = 0; j < similar_part_length; j++) {
      CHECK(pos1 + j < len1);
      CHECK(pos2 + j < len2);
      CHECK_EQ(s1[pos1 + j], s2[pos2 + j]);
    }
  }

  if (expected_diff_parameter != -1) {
    CHECK_EQ(expected_diff_parameter, diff_parameter);
  }
}


void CompareStrings(const char* s1, const char* s2,
                    int expected_diff_parameter = -1) {
  CompareStringsOneWay(s1, s2, expected_diff_parameter);
  CompareStringsOneWay(s2, s1, expected_diff_parameter);
}

}  // Anonymous namespace.


// --- T h e   A c t u a l   T e s t s

TEST(LiveEditDiffer) {
  CompareStrings("zz1zzz12zz123zzz", "zzzzzzzzzz", 6);
  CompareStrings("zz1zzz12zz123zzz", "zz0zzz0zz0zzz", 9);
  CompareStrings("123456789", "987654321", 16);
  CompareStrings("zzz", "yyy", 6);
  CompareStrings("zzz", "zzz12", 2);
  CompareStrings("zzz", "21zzz", 2);
  CompareStrings("cat", "cut", 2);
  CompareStrings("ct", "cut", 1);
  CompareStrings("cat", "ct", 1);
  CompareStrings("cat", "cat", 0);
  CompareStrings("", "", 0);
  CompareStrings("cat", "", 3);
  CompareStrings("a cat", "a capybara", 7);
  CompareStrings("abbabababababaaabbabababababbabbbbbbbababa",
                 "bbbbabababbbabababbbabababababbabbababa");
}

}  // namespace internal
}  // namespace v8
