// Copyright 2013 The Flutter Authors. 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:core' hide RegExp;

import 'patterns.dart';

void _stripFullLines(List<String> lines) {
  // Strip full-line decorations, e.g. horizontal lines, and trailing whitespace.
  for (int index = 0; index < lines.length; index += 1) {
    lines[index] = lines[index].trimRight();
    if (fullDecorations.matchAsPrefix(lines[index]) != null) {
      if (index == 0 || lines[index].length != lines[index - 1].length) {
        // (we leave the decorations if it's just underlining the previous line)
        lines[index] = '';
      }
    }
  }
  // Remove leading and trailing blank lines
  while (lines.isNotEmpty && lines.first == '') {
    lines.removeAt(0);
  }
  while (lines.isNotEmpty && lines.last == '') {
    lines.removeLast();
  }
}

bool _stripIndentation(List<String> lines) {
  // Try stripping leading indentation.
  String? prefix;
  bool removeTrailingBlockEnd = false;
  if (lines.first.startsWith('/*') && lines.last.startsWith(' *')) {
    // In addition to the leadingDecorations, we also support one specific
    // kind of multiline decoration, the /*...*/ block comment.
    prefix = ' *';
    removeTrailingBlockEnd = true;
  } else {
    prefix = leadingDecorations.matchAsPrefix(lines.first)?.group(0);
  }
  if (prefix != null && lines.skip(1).every((String line) => line.startsWith(prefix!) || prefix.startsWith(line))) {
    final int prefixLength = prefix.length;
    for (int index = 0; index < lines.length; index += 1) {
      final String line = lines[index];
      if (line.length > prefixLength) {
        lines[index] = line.substring(prefixLength);
      } else {
        lines[index] = '';
      }
    }
    if (removeTrailingBlockEnd) {
      if (lines.last == '/') {
        // This removes the line with the trailing "*/" when we had a "/*" at the top.
        lines.removeLast();
      }
    }
    return true;
  }
  return false;
}

bool _unindentLeadingParagraphs(List<String> lines) {
  // Try removing leading spaces
  // (we know that this loop terminates before the end of the block because
  // otherwise the previous section would have stripped a common prefix across
  // the entire block)
  //
  // For example, this will change:
  //
  //     foo
  //   bar
  //
  // ...into:
  //
  //   foo
  //   bar
  //
  assert(' '.startsWith(leadingDecorations));
  if (lines.first.startsWith(' ')) {
    int lineCount = 0;
    String line = lines.first;
    int leadingBlockIndent = line.length; // arbitrarily big number
    do {
      int indentWidth = 1;
      while (indentWidth < line.length && line[indentWidth] == ' ') {
        indentWidth += 1;
      }
      if (indentWidth < leadingBlockIndent) {
        leadingBlockIndent = indentWidth;
      }
      lineCount += 1;
      assert(lineCount < lines.length);
      line = lines[lineCount];
    } while (line.startsWith(' '));
    assert(leadingBlockIndent > 0);
    for (int index = 0; index < lineCount; index += 1) {
      lines[index] = lines[index].substring(leadingBlockIndent, lines[index].length);
    }
    return true;
  }
  return false;
}

bool _minorRemovals(List<String> lines) {
  bool didEdits = false;
  // Try removing stray leading spaces (but only one space).
  for (int index = 0; index < lines.length; index += 1) {
    if (lines[index].startsWith(' ') && !lines[index].startsWith('  ')) {
      lines[index] = lines[index].substring(1, lines[index].length);
      didEdits = true;
    }
  }
  // Try stripping HTML leading and trailing block (<!--/-->) comment markers.
  if (lines.first.contains('<!--') || lines.last.contains('-->')) {
    lines.first = lines[0].replaceFirst('<!--', '');
    lines.last = lines[0].replaceFirst('-->', '');
    didEdits = true;
  }
  // Try stripping C-style leading block comment markers.
  // We don't do this earlier because if it's a multiline block comment
  // we want to be careful about stripping the trailing aligned "*/".
  if (lines.first.startsWith('/*')) {
    lines.first = lines.first.substring(2, lines.first.length);
    didEdits = true;
  }
  // Try stripping trailing decorations (specifically, stray "*/"s).
  for (int index = 0; index < lines.length; index += 1) {
    if (lines[index].endsWith('*/')) {
      lines[index] = lines[index].substring(0, lines[index].length - 2);
      didEdits = true;
    }
  }
  return didEdits;
}

/// This function takes a block of text potentially decorated with leading
/// prefix indents, horizontal lines, C-style comment blocks, blank lines, etc,
/// and removes all such incidental material leaving only the significant text.
String reformat(String body) {
  final List<String> lines = body.split('\n');
  while (true) {
    // The order of the following checks is important. If any test changes
    // something that could affect an earlier test, then we should "continue" back
    // to the top of the loop.
    _stripFullLines(lines);
    if (lines.isEmpty) {
      // We've stripped everything, give up.
      return '';
    }
    if (_stripIndentation(lines)) {
      continue; // Go back to top since we may have more blank lines to strip now.
    }
    if (_unindentLeadingParagraphs(lines)) {
      continue; // Go back to the top since we may have more indentation to strip now.
    }
    if (_minorRemovals(lines)) {
      continue; // Go back to the top since we may have new stuff to strip.
    }
    // If we get here, we could not find anything else to do to the text to clean it up.
    break;
  }
  return lines.join('\n');
}

String stripAsciiArt(String input) {
  // Look for images so that we can remove them.
  final List<String> lines = input.split('\n');
  for (final List<String> image in asciiArtImages) {
    assert(image.isNotEmpty);
    // Look for the image starting on each line.
    search: for (int index = 0; index < lines.length - image.length; index += 1) {
      final int x = lines[index].indexOf(image[0]);
      if (x >= 0) {
        int width = image[0].length;
        // Found the first line, check to see if we have a complete image.
        for (int imageLine = 1; imageLine < image.length; imageLine += 1) {
          if (lines[index + imageLine].indexOf(image[imageLine]) != x) {
            continue search; // Not a complete image.
          }
          if (image[imageLine].length > width) {
            width = image[imageLine].length;
          }
        }
        // Now remove the image.
        for (int imageLine = 0; imageLine < image.length; imageLine += 1) {
          final String text = lines[index + imageLine];
          assert(text.length > x);
          if (text.length >= x + width) {
            lines[index + imageLine] = text.substring(0, x) + text.substring(x + width, text.length);
          } else {
            lines[index + imageLine] = text.substring(0, x);
          }
        }
      }
    }
  }
  return lines.join('\n');
}
