// Copyright (c) 2019, 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' show File, stdin, stdout;

import "utils/io_utils.dart";

final Uri repoDir = computeRepoDirUri();

enum Dictionaries {
  common,
  cfeMessages,
  cfeCode,
  cfeTests,
  // The denylist is special and is always loaded!
  denylist,
}

Map<Dictionaries, Set<String>>? loadedDictionaries;

SpellingResult spellcheckString(String s,
    {List<Dictionaries>? dictionaries, bool splitAsCode: false}) {
  dictionaries ??= const [Dictionaries.common];
  ensureDictionariesLoaded(dictionaries);

  List<String>? wrongWords;
  List<List<String>?>? wrongWordsAlternatives;
  List<int>? wrongWordsOffset;
  List<bool>? wrongWordDenylisted;
  List<int> wordOffsets = <int>[];
  List<String> words =
      splitStringIntoWords(s, wordOffsets, splitAsCode: splitAsCode);
  List<Set<String>> dictionariesUnpacked = [];
  for (int j = 0; j < dictionaries.length; j++) {
    Dictionaries dictionaryType = dictionaries[j];
    if (dictionaryType == Dictionaries.denylist) continue;
    Set<String> dictionary = loadedDictionaries![dictionaryType]!;
    dictionariesUnpacked.add(dictionary);
  }
  for (int i = 0; i < words.length; i++) {
    String word = words[i].toLowerCase();
    int offset = wordOffsets[i];
    bool found = false;

    for (int j = 0; j < dictionariesUnpacked.length; j++) {
      Set<String> dictionary = dictionariesUnpacked[j];
      if (dictionary.contains(word)) {
        found = true;
        break;
      }
    }
    if (!found) {
      wrongWords ??= [];
      wrongWords.add(word);
      wrongWordsAlternatives ??= [];
      wrongWordsAlternatives.add(findAlternatives(word, dictionariesUnpacked));
      wrongWordsOffset ??= [];
      wrongWordsOffset.add(offset);
      wrongWordDenylisted ??= [];
      wrongWordDenylisted
          .add(loadedDictionaries![Dictionaries.denylist]!.contains(word));
    }
  }

  return new SpellingResult(wrongWords, wrongWordsOffset, wrongWordDenylisted,
      wrongWordsAlternatives);
}

List<String>? findAlternatives(String word, List<Set<String>> dictionaries) {
  List<String>? result;

  bool check(String w) {
    for (int j = 0; j < dictionaries.length; j++) {
      Set<String> dictionary = dictionaries[j];
      if (dictionary.contains(w)) return true;
    }
    return false;
  }

  void ok(String w) {
    (result ??= <String>[]).add(w);
  }

  // Delete a letter, insert a letter or change a letter and lookup.
  for (int i = 0; i < word.length; i++) {
    String before = word.substring(0, i);
    String after = word.substring(i + 1);
    String afterIncluding = word.substring(i);

    {
      String deletedLetter = before + after;
      if (check(deletedLetter)) ok(deletedLetter);
    }
    for (int j = 0; j < 25; j++) {
      String c = new String.fromCharCode(97 + j);
      String insertedLetter = before + c + afterIncluding;
      if (check(insertedLetter)) ok(insertedLetter);
    }
    for (int j = 0; j < 25; j++) {
      String c = new String.fromCharCode(97 + j);
      String replacedLetter = before + c + after;
      if (check(replacedLetter)) ok(replacedLetter);
    }
  }

  return result;
}

class SpellingResult {
  final List<String>? misspelledWords;
  final List<int>? misspelledWordsOffset;
  final List<bool>? misspelledWordsDenylisted;
  final List<List<String>?>? misspelledWordsAlternatives;

  SpellingResult(this.misspelledWords, this.misspelledWordsOffset,
      this.misspelledWordsDenylisted, this.misspelledWordsAlternatives);
}

void ensureDictionariesLoaded(List<Dictionaries> dictionaries) {
  void addWords(Uri uri, Set<String> dictionary) {
    for (String word in File.fromUri(uri)
        .readAsStringSync()
        .split("\n")
        .map((s) => s.toLowerCase())) {
      if (word.startsWith("#")) continue;
      int indexOfHash = word.indexOf(" #");
      if (indexOfHash >= 0) {
        // Strip out comment.
        word = word.substring(0, indexOfHash).trim();
      }
      if (word == "") continue;
      if (word.contains(" ")) throw "'$word' contains spaces";
      dictionary.add(word);
    }
  }

  loadedDictionaries ??= new Map<Dictionaries, Set<String>>();
  // Ensure the denylist is loaded.
  Set<String>? denylistDictionary = loadedDictionaries![Dictionaries.denylist];
  if (denylistDictionary == null) {
    denylistDictionary = new Set<String>();
    loadedDictionaries![Dictionaries.denylist] = denylistDictionary;
    addWords(dictionaryToUri(Dictionaries.denylist), denylistDictionary);
  }

  for (int j = 0; j < dictionaries.length; j++) {
    Dictionaries dictionaryType = dictionaries[j];
    Set<String>? dictionary = loadedDictionaries![dictionaryType];
    if (dictionary == null) {
      dictionary = new Set<String>();
      loadedDictionaries![dictionaryType] = dictionary;
      addWords(dictionaryToUri(dictionaryType), dictionary);
      // Check that no good words occur in the denylist.
      for (String s in dictionary) {
        if (denylistDictionary.contains(s)) {
          throw "Word '$s' in dictionary $dictionaryType "
              "is also in the denylist.";
        }
      }
    }
  }
}

Uri dictionaryToUri(Dictionaries dictionaryType) {
  switch (dictionaryType) {
    case Dictionaries.common:
      return repoDir
          .resolve("pkg/front_end/test/spell_checking_list_common.txt");
    case Dictionaries.cfeMessages:
      return repoDir
          .resolve("pkg/front_end/test/spell_checking_list_messages.txt");
    case Dictionaries.cfeCode:
      return repoDir.resolve("pkg/front_end/test/spell_checking_list_code.txt");
    case Dictionaries.cfeTests:
      return repoDir
          .resolve("pkg/front_end/test/spell_checking_list_tests.txt");
    case Dictionaries.denylist:
      return repoDir
          .resolve("pkg/front_end/test/spell_checking_list_denylist.txt");
  }
}

List<String> splitStringIntoWords(String s, List<int> splitOffsets,
    {bool splitAsCode: false}) {
  List<String> result = <String>[];
  // Match whitespace and the characters "-", "=", "|", "/", ",".
  String regExpStringInner = r"\s-=\|\/,";
  if (splitAsCode) {
    // If splitting as code also split by "_", ":", ".", "(", ")", "<", ">",
    // "[", "]", "{", "}", "@", "&", "#", "?", "%", "`", '"', and numbers.
    // (As well as doing stuff to camel casing further below).
    regExpStringInner =
        "${regExpStringInner}_:\\.\\(\\)<>\\[\\]\{\}@&#\\?%`\"0123456789";
  }
  // Match one or more of the characters specified above.
  String regExp = "[$regExpStringInner]+";
  if (splitAsCode) {
    // If splitting as code we also want to remove the two characters "\n".
    regExp = "([$regExpStringInner]|(\\\\n))+";
  }

  Iterator<RegExpMatch> matchesIterator =
      new RegExp(regExp).allMatches(s).iterator;
  int latestMatch = 0;
  List<String> split = <String>[];
  List<int> splitOffset = <int>[];
  while (matchesIterator.moveNext()) {
    RegExpMatch match = matchesIterator.current;
    if (match.start > latestMatch) {
      split.add(s.substring(latestMatch, match.start));
      splitOffset.add(latestMatch);
    }
    latestMatch = match.end;
  }
  if (s.length > latestMatch) {
    split.add(s.substring(latestMatch, s.length));
    splitOffset.add(latestMatch);
  }

  for (int i = 0; i < split.length; i++) {
    String word = split[i];
    int offset = splitOffset[i];
    if (word.isEmpty) continue;
    int start = 0;
    int end = word.length;
    bool changedStart = false;
    while (start < end) {
      int unit = word.codeUnitAt(start);
      if (unit >= 65 && unit <= 90) {
        // A-Z => Good.
        break;
      } else if (unit >= 97 && unit <= 122) {
        // a-z => Good.
        break;
      } else {
        changedStart = true;
        start++;
      }
    }
    bool changedEnd = false;
    while (end > start) {
      int unit = word.codeUnitAt(end - 1);
      if (unit >= 65 && unit <= 90) {
        // A-Z => Good.
        break;
      } else if (unit >= 97 && unit <= 122) {
        // a-z => Good.
        break;
      } else {
        changedEnd = true;
        end--;
      }
    }
    if (changedEnd && word.codeUnitAt(end) == 41) {
      // Special case trimmed ')' if there's a '(' inside the string.
      for (int i = start; i < end; i++) {
        if (word.codeUnitAt(i) == 40) {
          end++;
          break;
        }
      }
    }
    if (start == end) continue;

    if (splitAsCode) {
      bool prevCapitalized = false;
      for (int i = start; i < end; i++) {
        bool thisCapitalized = false;
        int unit = word.codeUnitAt(i);
        if (unit >= 65 && unit <= 90) {
          thisCapitalized = true;
        } else if (unit >= 48 && unit <= 57) {
          // Number inside --- allow that.
          continue;
        }
        if (prevCapitalized && thisCapitalized) {
          // Sort-of-weird thing, something like "thisIsTheCNN". Carry on.

          // Except if the previous was an 'A' and that both the previous
          // (before that) and the next (if any) is not capitalized, i.e.
          // we special-case the case of 'A' as in 'AWord' being 'a word'.
          int prevUnit = word.codeUnitAt(i - 1);
          if (prevUnit == 65) {
            bool doSpecialCase = true;
            if (i + 1 < end) {
              int nextUnit = word.codeUnitAt(i + 1);
              if (nextUnit >= 65 && nextUnit <= 90) {
                // Next is capitalized too.
                doSpecialCase = false;
              }
            }
            if (i - 2 >= start) {
              int prevPrevUnit = word.codeUnitAt(i - 2);
              if (prevPrevUnit >= 65 && prevPrevUnit <= 90) {
                // Prev-prev was capitalized too.
                doSpecialCase = false;
              }
            }
            if (doSpecialCase) {
              result.add(word.substring(start, i));
              splitOffsets.add(offset + start);
              start = i;
            }
          }

          // And the case where the next one is not capitalized --- we must
          // assume that "TheCNNAlso" should be "The", "CNN", "Also".
          if (start < i && i + 1 < end) {
            int nextUnit = word.codeUnitAt(i + 1);
            if (nextUnit >= 97 && nextUnit <= 122) {
              // Next is not capitalized.
              result.add(word.substring(start, i));
              splitOffsets.add(offset + start);
              start = i;
            }
          }
        } else if (!prevCapitalized && thisCapitalized) {
          // Starting a new camel case word.
          if (i > start) {
            result.add(word.substring(start, i));
            splitOffsets.add(offset + start);
            start = i;
          }
        } else if (prevCapitalized && !thisCapitalized) {
          // This should have been handled above.
        } else if (!prevCapitalized && !thisCapitalized) {
          // Continued word.
        }
        if (i + 1 == end) {
          // End of string.
          if (i >= start) {
            result.add(word.substring(start, end));
            splitOffsets.add(offset + start);
          }
        }
        prevCapitalized = thisCapitalized;
      }
    } else {
      result.add(
          (changedStart || changedEnd) ? word.substring(start, end) : word);
      splitOffsets.add(offset + start);
    }
  }
  return result;
}

void spellSummarizeAndInteractiveMode(
    Set<String> reportedWords,
    Set<String> reportedWordsDenylisted,
    List<Dictionaries> dictionaries,
    bool interactive,
    String interactiveLaunchExample) {
  if (reportedWordsDenylisted.isNotEmpty) {
    print("\n\n\n");
    print("================");
    print("The following words was reported as used and denylisted:");
    print("----------------");
    for (String s in reportedWordsDenylisted) {
      print("$s");
    }
    print("================");
  }
  if (reportedWords.isNotEmpty) {
    print("\n\n\n");
    print("================");
    print("The following word(s) were reported as unknown:");
    print("----------------");

    Dictionaries? dictionaryToUse;
    if (dictionaries.contains(Dictionaries.cfeTests)) {
      dictionaryToUse = Dictionaries.cfeTests;
    } else if (dictionaries.contains(Dictionaries.cfeMessages)) {
      dictionaryToUse = Dictionaries.cfeMessages;
    } else if (dictionaries.contains(Dictionaries.cfeCode)) {
      dictionaryToUse = Dictionaries.cfeCode;
    } else {
      for (Dictionaries dictionary in dictionaries) {
        if (dictionaryToUse == null ||
            dictionary.index < dictionaryToUse.index) {
          dictionaryToUse = dictionary;
        }
      }
    }

    if (interactive && dictionaryToUse != null) {
      List<String> addedWords = <String>[];
      for (String s in reportedWords) {
        print("- $s");
        String answer;
        bool? add;
        while (true) {
          stdout.write("Do you want to add the word to the dictionary "
              "$dictionaryToUse (y/n)? ");
          answer = stdin.readLineSync()!.trim().toLowerCase();
          switch (answer) {
            case "y":
            case "yes":
            case "true":
              add = true;
              break;
            case "n":
            case "no":
            case "false":
              add = false;
              break;
            default:
              add = null;
              print("'$answer' is not a valid answer. Please try again.");
              break;
          }
          if (add != null) break;
        }
        if (add) {
          addedWords.add(s);
        }
      }
      if (addedWords.isNotEmpty) {
        File dictionaryFile =
            new File.fromUri(dictionaryToUri(dictionaryToUse));
        List<String> lines = dictionaryFile.readAsLinesSync();
        List<String> header = <String>[];
        List<String> sortThis = <String>[];
        for (String line in lines) {
          if (line.startsWith("#")) {
            header.add(line);
          } else if (line.trim().isEmpty && sortThis.isEmpty) {
            header.add(line);
          } else if (line.trim().isNotEmpty) {
            sortThis.add(line);
          }
        }
        sortThis.addAll(addedWords);
        sortThis.sort();
        lines = <String>[];
        lines.addAll(header);
        if (header.isEmpty || header.last.isNotEmpty) {
          lines.add("");
        }
        lines.addAll(sortThis);
        lines.add("");
        dictionaryFile.writeAsStringSync(lines.join("\n"));
      }
    } else {
      for (String s in reportedWords) {
        print("$s");
      }
      if (dictionaries.isNotEmpty) {
        print("----------------");
        print("If the word(s) are correctly spelled please add it to one of "
            "these files:");
        for (Dictionaries dictionary in dictionaries) {
          print(" - ${dictionaryToUri(dictionary)}");
        }

        print("");
        print("To add words easily, try to run this script in interactive "
            "mode via the command");
        print(interactiveLaunchExample);
      }
    }
    print("================");
  }
}
