// Copyright 2018 The diff-match-patch 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.

// This code (especially GetBisectSplitPoints) derive in part from
// diff_match_patch.cpp under the Apache 2.0 license and attribution:
//
// Author: fraser@google.com (Neil Fraser)
// Author: mikeslemmer@gmail.com (Mike Slemmer)
//
// Diff Match and Patch
// https://github.com/google/diff-match-patch

// Returns the minimal number of edit operations (copy, delete, insert)
// needed to tranform one container of tokens into another (cf. `diff -d -e`).
// Requires random-access iterators of token streams.

#ifndef EDITSCRIPT_H_
#define EDITSCRIPT_H_

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <map>
#include <tuple>
#include <utility>
#include <vector>

namespace diff {

enum class Operation { EQUALS, DELETE, INSERT };

/**
 * The data structure of edit operations to transform tokens1 into tokens2.
 * Indices for EQUALS and DELETE point into tokens1, INSERT into tokens2.
 * Concatenating EQUALS and DELETE tokens will return tokens1.
 * Concatenating EQUALS and INSERT tokens will return tokens2.
 * [start, end) is a semiopen interval.
 */
struct Edit {
  Operation operation;  // One of: EQUALS, DELETE, or INSERT.
  int64_t start;        // Start offset into tokens1 (tokens2 for INSERT).
  int64_t end;          // End   offset into tokens1 (tokens2 for INSERT).
  bool operator==(const Edit &rhs) const {
    return (std::tie(operation, start, end) ==
            std::tie(rhs.operation, rhs.start, rhs.end));
  }
  bool operator<(const Edit &rhs) const {
    return (std::tie(operation, start, end) <
            std::tie(rhs.operation, rhs.start, rhs.end));
  }
};
using Edits = std::vector<Edit>;

/**
 * Finds the differences between two vectors of tokens, returning edits
 * required to transform tokens1 into tokens2.
 * Every token in the combined document belongs to exactly one edit.
 *
 * For example, for tokens1 = "Hello world." and tokens2 = "Goodbye world.":
 * {Edit(Operation::DELETE, 0, 5),   // token1[0,5)   == "Hello"
 *  Edit(Operation::INSERT, 0, 7),   // token2[0,7)   == "Goodbye"
 *  Edit(Operation::EQUALS, 5, 12)}  // token1[5, 12) == " world."
 *
 * @param tokens1_begin Beginning index into tokens1.
 * @param tokens1_end   Ending index into tokens1.
 * @param tokens2_begin Beginning index into tokens2.
 * @param tokens2_end   Ending index into tokens2.
 * @return Cumulative edits to transform tokens1 into tokens2.
 */
template <typename TokenIter>
Edits GetTokenDiffs(TokenIter tokens1_begin, TokenIter tokens1_end,
                    TokenIter tokens2_begin, TokenIter tokens2_end);

//////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION
//////////////////////////////////////////////////////////////////////////////

namespace diff_impl {
/**
 * Appends an edit operation to the cumulative edits.
 * Fuses with previous edit if possible.
 * @param op    Edit operation.
 * @param start Start offset into tokens1 (tokens2 for INSERT).
 * @param end   End offset into tokens1 (tokens2 for INSERT).
 * @param edits Cumulative vector of edits (inout).
 */
inline void AppendEdit(Operation op, int64_t start, int64_t end, Edits *edits) {
  if (!edits->empty() &&
      edits->back().operation == op &&
      edits->back().end == start) {
    // Merge into previous edit operation.
    edits->back().end = end;
  } else {
    // Add a new edit operation.
    edits->emplace_back(Edit{op, start, end});
  }
}

/**
 * Inserts an edit operation into the cumulative edits at given index.
 * Fuses with neighboring edit if possible.
 * @param index Index of insertion point.
 * @param op    Edit operation.
 * @param start Start offset into tokens1 (tokens2 for INSERT).
 * @param end   End offset into tokens1 (tokens2 for INSERT).
 * @param edits Cumulative vector of edits (inout).
 */
inline void InsertEditAt(int64_t index, Operation op, int64_t start,
                         int64_t end, Edits *edits) {
  if (index > 0) {
    Edit &prev_edit = (*edits)[index - 1];
    if (prev_edit.operation == op &&
        prev_edit.end == start) {
      // Merge into previous edit operation.
      prev_edit.end = end;
      return;
    }
  }
  if (index < static_cast<int64_t>(edits->size())) {
    Edit &next_edit = (*edits)[index];
    if (next_edit.operation == op &&
        next_edit.end == start) {
      // Merge into subsequent edit operation.
      next_edit.end = end;
      return;
    }
  }

  // Cannot merge into existing? Insert a new edit operation.
  edits->emplace(edits->begin() + index, Edit{op, start, end});
}

/**
 * Reverse direction of iterator (without moving its location).
 * Returned iter will now point to one elem to left of input iter.
 * @param iter Original bidirectional or random iterator.
 */
template <typename TokenIter>
inline std::reverse_iterator<TokenIter> Reverse(TokenIter iter) {
  return std::reverse_iterator<TokenIter>(iter);
}

/**
 * Determine the common affix of two tokens.
 * For common prefix, pass normal iterators.
 * For common suffix, pass reverse iterators.
 * @param span1_begin Beginning iterator into tokens1.
 * @param span1_end   Ending iterator into tokens1.
 * @param span2_begin Beginning iterator into tokens2.
 * @param span2_end   Ending iterator into tokens2.
 * @return The number of tokens common to the start of spans.
 */
template <typename TokenIter>
inline int64_t CommonAffix(TokenIter span1_begin, TokenIter span1_end,
                           TokenIter span2_begin, TokenIter span2_end) {
  // std::mismatch wants the shorter container first.
  if (span1_end - span1_begin > span2_end - span2_begin) {
    using std::swap;
    swap(span1_begin, span2_begin);
    swap(span1_end, span2_end);
  }

  auto affix_ends = std::mismatch(span1_begin, span1_end, span2_begin);
  const int64_t affix_length = affix_ends.first - span1_begin;
  return affix_length;
}

/**
 * Finds the differences between two vectors of tokens.
 * Invoke using GetTokenDiffs.
 */
template <typename TokenIter>
class Diff {
 private:
  friend Edits
  GetTokenDiffs<>(TokenIter tokens1_begin, TokenIter tokens1_end,
                  TokenIter tokens2_begin, TokenIter tokens2_end);

  /**
   * Finds the differences between two vectors of tokens, returning edits
   * required to transform tokens1 into tokens2.
   * Every token in the combined document belongs to exactly one edit.
   * @param tokens1_begin Iterator pointing to start of tokens1.
   * @param tokens2_begin Iterator pointing to start of tokens2.
   * @param edits Cumulative edits to transform tokens1 into tokens2 (inout).
   */
  Diff(TokenIter tokens1_begin, TokenIter tokens2_begin)
      : tokens1_begin_(tokens1_begin), tokens2_begin_(tokens2_begin) {}

  /**
   * Find the differences between two vectors of tokens.
   * @param b1 Beginning index into tokens1.
   * @param e1 Ending index into tokens1.
   * @param b2 Beginning index into tokens2.
   * @param e2 Ending index into tokens2.
   * @param edits Cumulative edits to transform tokens1 into tokens2 (inout).
   * @param edits Vector of Edit objects
   */
  void Generate(int64_t b1, int64_t e1, int64_t b2, int64_t e2,
                Edits *edits) const {
    // Avoid growing stack through recursion more than necessary.
    int64_t prefix_size = 0;
    int64_t suffix_size = 0;
    int64_t edits_size = 0;
    {
      // The diff strategy is to recursively:
      // - Peel off common prefix and suffix
      // - Split what's left in two parts
      // - Generate diffs for each and combine.
      // The diffs could be done in parallel (with a fresh edits) and
      // later combined if speed up is needed.
      auto span1_begin = tokens1_begin_ + b1;
      auto span2_begin = tokens2_begin_ + b2;
      auto span1_end = tokens1_begin_ + e1;
      auto span2_end = tokens2_begin_ + e2;

      // Check for equality (speedup).
      if ((e1 - b1) == (e2 - b2) &&
          std::equal(span1_begin, span1_end, span2_begin)) {
        if (span1_begin != span1_end) {
          AppendEdit(Operation::EQUALS, b1, e1, edits);
        }
        return;
      }

      // Find longest common prefix and suffix.
      prefix_size =
          CommonAffix(span1_begin, span1_end, span2_begin, span2_end);
      suffix_size =
          CommonAffix(Reverse(span1_end), Reverse(span1_begin + prefix_size),
                      Reverse(span2_end), Reverse(span2_begin + prefix_size));

      // Remember the current location so we can insert a common prefix.
      edits_size = edits->size();
    }

    // Compute the diff on the middle block.
    Compute(b1 + prefix_size, e1 - suffix_size,
            b2 + prefix_size, e2 - suffix_size,
            edits);

    // Restore the prefix and suffix.
    if (prefix_size != 0) {
      InsertEditAt(edits_size, Operation::EQUALS, b1, b1 + prefix_size, edits);
    }
    if (suffix_size != 0) {
      AppendEdit(Operation::EQUALS, e1 - suffix_size, e1, edits);
    }
  }

  /**
   * Find the differences between two vectors of tokens.
   * @pre Tokens are not equal nor share a common prefix or suffix.
   * @param b1 Beginning index into tokens1.
   * @param e1 Ending index into tokens1.
   * @param b2 Beginning index into tokens2.
   * @param e2 Ending index into tokens2.
   * @param edits Cumulative edits to transform tokens1 into tokens2 (inout).
   */
  void Compute(int64_t b1, int64_t e1, int64_t b2, int64_t e2,
               Edits *edits) const {
    // Try various speedups first.
    // Enclose in a scope to save stack space before recursing.
    {
      const int64_t length1 = e1 - b1;
      const int64_t length2 = e2 - b2;
      if (length1 == 0 && length2 != 0) {
        // tokens1 empty, but tokens2 isn't: Just insert tokens2
        AppendEdit(Operation::INSERT, b2, e2, edits);
        return;
      }
      if (length2 == 0 && length1 != 0) {
        // tokens2 empty, but tokens1 isn't: Just delete tokens1
        AppendEdit(Operation::DELETE, b1, e1, edits);
        return;
      }
      if (length1 > length2) {
        const int64_t offset =
            std::search(tokens1_begin_ + b1, tokens1_begin_ + e1,
                        tokens2_begin_ + b2, tokens2_begin_ + e2) -
            tokens1_begin_;
        if (offset != e1) {
          // tokens2 is a proper substring of tokens1: delete the rest.
          const int64_t offset_end = offset + length2;
          AppendEdit(Operation::DELETE, b1, offset, edits);
          AppendEdit(Operation::EQUALS, offset, offset_end, edits);
          AppendEdit(Operation::DELETE, offset_end, e1, edits);
          return;
        }
        if (length2 == 1) {
          // Single-token span.
          // After the previous speedup, the operation can't be EQUALS.
          AppendEdit(Operation::DELETE, b1, e1, edits);
          AppendEdit(Operation::INSERT, b2, e2, edits);
          return;
        }
      } else if (length2 > length1) {
        const int64_t offset =
            std::search(tokens2_begin_ + b2, tokens2_begin_ + e2,
                        tokens1_begin_ + b1, tokens1_begin_ + e1) -
            tokens2_begin_;
        if (offset != e2) {
          // tokens1 is a proper substring of tokens2: insert the rest.
          AppendEdit(Operation::INSERT, b2, offset, edits);
          AppendEdit(Operation::EQUALS, b1, e1, edits);  // Index into tokens1!
          AppendEdit(Operation::INSERT, offset + length1, e2, edits);
          return;
        }
        if (length1 == 1) {
          // Single-token span.
          // After the previous speedup, the operation can't be EQUALS.
          AppendEdit(Operation::DELETE, b1, e1, edits);
          AppendEdit(Operation::INSERT, b2, e2, edits);
          return;
        }
      }
    }

    // No speedups apply? Bisect and diff each half, then combine results.
    Bisect(b1, e1, b2, e2, edits);
  }

  /**
   * Find the 'middle snake' of a diff, returning split points.
   * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.
   * @param b1    Beginning index into tokens1.
   * @param e1    Ending index into tokens1.
   * @param b2    Beginning index into tokens2.
   * @param e2    Ending index into tokens2.
   * @return Index of split points in tokens1 and tokens2, respectively.
   *     Returns {-1, -1} if there is no need to bisect.
   */
  std::pair<int64_t, int64_t> GetBisectSplitPoints(int64_t b1, int64_t e1,
                                                   int64_t b2,
                                                   int64_t e2) const {
    std::pair<int64_t, int64_t> splits;
    int64_t &x1 = splits.first;
    int64_t &y1 = splits.second;

    const int64_t length1 = e1 - b1;
    const int64_t length2 = e2 - b2;
    const int64_t max_d = (length1 + length2 + 1) / 2;
    const int64_t v_offset = max_d;
    const int64_t v_size = 2 * max_d;
    const int64_t w_size = 2 * v_size;
    std::vector<int64_t> w(w_size + 4,
                           -1);  // interleave for cache friendliness

    w[2 * v_offset + 2] = 0;
    w[2 * v_offset + 3] = 0;
    const int64_t delta = length1 - length2;

    // If the total number of tokens is odd, then the front path will
    // collide with the reverse path.
    const bool front = (delta % 2 != 0);

    // Offsets for start and end of k loop.
    // Prevents mapping of space beyond the grid.
    int64_t k1start = 0;
    int64_t k1end = 0;
    int64_t k2start = 0;
    int64_t k2end = 0;
    for (int64_t d = 0; d < max_d; d++) {
      // Walk the front path one step.
      for (int64_t k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {
        const int64_t k1_offset = v_offset + k1;
        x1 = 0;
        if (k1 == -d ||
            (k1 != d && w[2 * k1_offset - 2] < w[2 * k1_offset + 2])) {
          x1 = w[2 * k1_offset + 2];
        } else {
          x1 = w[2 * k1_offset - 2] + 1;
        }
        y1 = x1 - k1;
        while (x1 < length1 && y1 < length2 &&
               *(tokens1_begin_ + (b1 + x1)) == *(tokens2_begin_ + (b2 + y1))) {
          x1++;
          y1++;
        }
        w[2 * k1_offset] = x1;
        if (x1 > length1) {
          // Ran off the right of the graph.
          k1end += 2;
        } else if (y1 > length2) {
          // Ran off the bottom of the graph.
          k1start += 2;
        } else if (front) {
          int64_t k2_offset = v_offset + delta - k1;
          if (k2_offset >= 0 && k2_offset < v_size &&
              w[2 * k2_offset + 1] != -1) {
            // Mirror x2 onto top-left coordinate system.
            int64_t x2 = length1 - w[2 * k2_offset + 1];
            if (x1 >= x2) {
              // Overlap detected.
              return splits;
            }
          }
        }
      }

      // Walk the reverse path one step.
      for (int64_t k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {
        const int64_t k2_offset = v_offset + k2;
        int64_t x2;
        if (k2 == -d ||
            (k2 != d && w[2 * k2_offset - 1] < w[2 * k2_offset + 3])) {
          x2 = w[2 * k2_offset + 3];
        } else {
          x2 = w[2 * k2_offset - 1] + 1;
        }
        int64_t y2 = x2 - k2;
        while (x2 < length1 && y2 < length2 &&
               *(tokens1_begin_ + (b1 + length1 - x2 - 1)) ==
               *(tokens2_begin_ + (b2 + length2 - y2 - 1))) {
          x2++;
          y2++;
        }
        w[2 * k2_offset + 1] = x2;
        if (x2 > length1) {
          // Ran off the left of the graph.
          k2end += 2;
        } else if (y2 > length2) {
          // Ran off the top of the graph.
          k2start += 2;
        } else if (!front) {
          int64_t k1_offset = v_offset + delta - k2;
          if (k1_offset >= 0 && k1_offset < v_size && w[2 * k1_offset] != -1) {
            x1 = w[2 * k1_offset];
            y1 = v_offset + x1 - k1_offset;

            // Mirror x2 onto top-left coordinate system.
            x2 = length1 - x2;
            if (x1 >= x2) {
              // Overlap detected.
              return splits;
            }
          }
        }
      }
    }
    x1 = -1;
    y1 = -1;
    return splits;
  }

  /**
   * Bisect and recurse if necessary.
   * @param b1    Beginning index into tokens1.
   * @param e1    Ending index into tokens1.
   * @param b2    Beginning index into tokens2.
   * @param e2    Ending index into tokens2.
   * @param edits Cumulative edits to transform tokens1 into tokens2 (inout).
   */
  void Bisect(int64_t b1, int64_t e1, int64_t b2, int64_t e2,
              Edits *edits) const {
    int64_t x1, x2;
    std::tie(x1, x2) = GetBisectSplitPoints(b1, e1, b2, e2);
    if (x1 >= 0) {
      // Some commonality, so bisect and recurse.
      Generate(b1, b1 + x1, b2, b2 + x2, edits);
      Generate(b1 + x1, e1, b2 + x2, e2, edits);
    } else {
      // No commonality at all (number of edits equals number of tokens),
      // so just delete the old and insert the new.
      AppendEdit(Operation::DELETE, b1, e1, edits);
      AppendEdit(Operation::INSERT, b2, e2, edits);
    }
  }

 private:
  TokenIter tokens1_begin_;
  TokenIter tokens2_begin_;
};  // class Diff
}  // namespace diff_impl

template <typename TokenIter>
inline Edits GetTokenDiffs(TokenIter tokens1_begin, TokenIter tokens1_end,
                           TokenIter tokens2_begin, TokenIter tokens2_end) {
  Edits token_edits;
  diff_impl::Diff<TokenIter>(tokens1_begin, tokens2_begin)
      .Generate(0, std::distance(tokens1_begin, tokens1_end),
                0, std::distance(tokens2_begin, tokens2_end),
                &token_edits);
  return token_edits;  // efficient: uses named return value optimization
}

}  // namespace diff

#endif  // EDITSCRIPT_H_
