// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';

import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
    show ErrorToken, ScannerConfiguration, StringScanner;
import 'package:_fe_analyzer_shared/src/scanner/token.dart'
    show BeginToken, SimpleToken, Token, TokenType;

class Duplicate {
  final List<FromToUri> where;
  final String example;

  Duplicate(this.where, this.example);

  @override
  String toString() => "Duplicate[$example]";
}

class FromToUri {
  final Uri uri;
  final int startOffset;
  final int endOffset;

  FromToUri(this.uri, this.startOffset, this.endOffset);
}

class Line {
  String content;
  Uri uri;
  int startOffset;
  int endOffset;
  Line? previous;
  Line? next;

  Line(
      this.content, this.uri, this.startOffset, this.endOffset, this.previous) {
    if (previous != null) {
      previous!.next = this;
    }
  }
}

class ExtendedLines {
  List<Line> startLines;
  int lineCount;

  ExtendedLines(this.startLines, this.lineCount);
}

class MultiMap<K, V> {
  Map<K, List<V>> data = {};

  void operator []=(K key, V value) {
    List<V>? lookup = data[key];
    if (lookup != null) {
      lookup.add(value);
    } else {
      data[key] = [value];
    }
  }
}

void _indexLines(MultiMap<String, Line> mapped, Set<String> denyListed,
    String data, Uri uri) {
  // TODO(jensj): Work directly on scanned tokens, or use parser as well?
  // * Should probably only operate on body content, and then not cross bracket
  //   boundaries in that it should suggest that "foo; } } bar;" is a duplicate
  //   -- while it might be duplicate, we can't replace that with a function
  //   call (to get rid of duplicate code).
  // * If something is a string we could perhaps ignore the content so that
/*
    assert(declaration.parent == _libraryTypeParameterScopeBuilder);
    Map<String, Builder> members = declaration.members!;
    Map<String, MemberBuilder> constructors = declaration.constructors!;
    Map<String, MemberBuilder> setters = declaration.setters!;

    Scope classScope = new Scope(
        local: members,
        setters: setters,
        parent: scope.withTypeVariables(typeVariables),
        debugName: "class $className",
        isModifiable: false);
*/
  //   and
/*
    assert(declaration.parent == _libraryTypeParameterScopeBuilder);
    Map<String, Builder> members = declaration.members!;
    Map<String, MemberBuilder> constructors = declaration.constructors!;
    Map<String, MemberBuilder> setters = declaration.setters!;

    Scope classScope = new Scope(
        local: members,
        setters: setters,
        parent: scope.withTypeVariables(typeVariables),
        debugName: "extension $extensionName",
        isModifiable: false);
*/
  //   could match.
  Token scannedToken = _scan(data);
  if (scannedToken is ErrorToken) throw "Can't operate on erroneous data";
  Token token = scannedToken;
  StringBuffer sb = new StringBuffer();
  String space = "";
  int? startOffset;

  List<Token> endGroups = [];
  Line? previousLine;

  void endLine(Token lastToken) {
    String s = sb.toString();
    int lineStart = startOffset!;
    sb.clear();
    space = "";
    startOffset = null;

    Line line = new Line(s, uri, lineStart, lastToken.charEnd, previousLine);
    previousLine = line;
    if (!denyListed.contains(s)) mapped[s] = line;
  }

  while (true) {
    sb.write(space);
    sb.write(token.lexeme);
    space = " ";
    startOffset ??= token.charOffset;

    if (endGroups.isNotEmpty && endGroups.last == token) {
      endLine(token);
      endGroups.removeLast();
    } else if (token is BeginToken &&
        token.type == TokenType.OPEN_CURLY_BRACKET &&
        token.endGroup != null) {
      // End line on a "{".
      endLine(token);
      endGroups.add(token.endGroup!);
    } else if (token is SimpleToken && token.type == TokenType.SEMICOLON) {
      // End line on a ";".
      endLine(token);
    } else if (token.next!.isEof) {
      endLine(token);
      break;
    }

    token = token.next!;
  }
}

void _extendIndexedLines(List<Line> lines, Set<Line> alreadyIncluded,
    List<Duplicate> foundDuplicates, Set<String> denyListed) {
  int length = lines.length;

  if (length == 1) {
    // The indexed line was only seen once. That's not a duplicate!
    return;
  }

  // We move forward in the data, and if having found a -> b -> c
  // after having processed 'a' we shouldn't process from 'b' too. We thus
  // remove already included lines here.
  for (Line line in lines) {
    if (alreadyIncluded.contains(line)) {
      length--;
    }
  }
  if (length <= 1) {
    // We've seen this line before, but all duplicates was included in another
    // actual duplicate find. Don't process and report again!
    return;
  }

  // Can this potential duplicate be extended?
  List<ExtendedLines>? extended = _extend(lines,
      existingMatchCount: 1, leastMatches: 3, denyListed: denyListed);
  if (extended == null || extended.isEmpty) return;
  for (ExtendedLines extendedLine in extended) {
    for (Line line in extendedLine.startLines) {
      int left = extendedLine.lineCount - 1;
      Line l = line;
      while (left > 0) {
        alreadyIncluded.add(l);
        left--;
        l = l.next!;
      }
    }
    List<FromToUri> where = [];
    StringBuffer sb = new StringBuffer();
    String? example;
    for (Line firstLine in extendedLine.startLines) {
      int left = extendedLine.lineCount - 1;
      Line lastLine = firstLine;
      if (example == null) sb.writeln(lastLine.content);
      while (left > 0) {
        left--;
        lastLine = lastLine.next!;
        if (example == null) sb.writeln(lastLine.content);
      }
      where.add(new FromToUri(
          firstLine.uri, firstLine.startOffset, lastLine.endOffset));
      example ??= sb.toString();
    }
    foundDuplicates.add(new Duplicate(where, example!));
  }
}

List<Duplicate> findDuplicates(Map<Uri, String> data, {bool verbose = false}) {
  MultiMap<String, Line> indexedLines = new MultiMap();
  const Set<String> denyListed = const {"}", "return ;", ";", ") ;", "else {"};

  for (MapEntry<Uri, String> entry in data.entries) {
    _indexLines(indexedLines, denyListed, entry.value, entry.key);
  }

  // TODO(jensj): The already included approach is too simple. E.g.
  /*
match1;
nomatch;

match0;
match1;
match2;
match3;

vs

match1;
nomatchX;

match0;
match1;
match2;
match3;

would first find match1 match2 match3 --- then match0 match1 match2 match3.
*/

  Set<Line> alreadyIncluded = {};
  List<Duplicate> result = [];
  for (MapEntry<String, List<Line>> entry in indexedLines.data.entries) {
    _extendIndexedLines(entry.value, alreadyIncluded, result, denyListed);
  }

  if (verbose) {
    if (result.length == 0) {
      print("Didn't find any duplicates.");
    } else if (result.length == 1) {
      print("Found 1 duplicate:");
    } else {
      print("Found ${result.length} duplicates:");
    }
    for (Duplicate duplicate in result) {
      print("Found '${duplicate.example}' at:");
      for (FromToUri where in duplicate.where) {
        print("${where.uri}: ${where.startOffset} -> ${where.endOffset}");
      }
      print("----\n\n");
    }
  }

  return result;
}

/// Given a list of lines that match, find duplicates that match on more lines,
/// thereby extending and possibly splitting the match.
List<ExtendedLines>? _extend(List<Line> lines,
    {required int existingMatchCount,
    required int leastMatches,
    required Set<String> denyListed}) {
  MultiMap<String, Line> mapped = new MultiMap();

  // E.g. for this input
  // a -> b1 -> c1 -> d1
  // a -> b1 -> c1 -> d2
  // a -> b2 -> c2 -> d1
  // a -> b2 -> c2 -> d2
  // a -> b3 -> c2 -> d1
  // we'd like it to be split into
  // [a, b1, c1] and [a, b2, c2]

  for (Line line in lines) {
    Line? next = line.next;
    if (next != null) {
      mapped[next.content] = next;
    }
  }

  List<ExtendedLines>? result;

  for (MapEntry<String, List<Line>> entry in mapped.data.entries) {
    if (entry.value.length == 1) {
      continue;
    }

    int newMatchCount = existingMatchCount + 1;
    // Don't count e.g. '}' as an actual match -> require one additional match.
    // Notice that we can't just not count it as that would destroy the count
    // which we use to go back and forth between first and last matched line.
    if (denyListed.contains(entry.key)) {
      leastMatches++;
    }

    List<ExtendedLines>? extended = _extend(entry.value,
        existingMatchCount: newMatchCount,
        leastMatches: leastMatches,
        denyListed: denyListed);
    if (extended != null) {
      // Was extended further.
      (result ??= []).addAll(extended);
    } else if (newMatchCount >= leastMatches) {
      // Couldn't be extended further, but this was far enough.
      (result ??= []).add(new ExtendedLines(
          entry.value.map((Line endLine) {
            Line line = endLine;
            int back = existingMatchCount;
            while (back > 0) {
              line = line.previous!;
              back--;
            }
            return line;
          }).toList(),
          newMatchCount));
    }
  }

  return result;
}

Token _scan(String data) {
  ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
      enableTripleShift: true,
      enableNonNullable: true,
      forAugmentationLibrary: false);

  StringScanner scanner =
      new StringScanner(data, configuration: scannerConfiguration);
  Token firstToken = scanner.tokenize();
  return firstToken;
}

void main(List<String> args) {
  if (args.isEmpty) {
    args = [
      Platform.script
          .resolve("../lib/src/source/source_library_builder.dart")
          .toFilePath()
    ];
  }
  bool printed = false;
  for (String s in args) {
    File f = new File(s);
    if (!f.existsSync()) continue;
    String data = f.readAsStringSync();

    if (printed) print("\n\n=============\n\n");
    print("Output on $s:");
    findDuplicates({Uri.parse(s): data}, verbose: true);
    printed = true;
  }
}
