// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:string_scanner/string_scanner.dart';

abstract class SyntaxPrehighlighter {
  List<CodeSpan> format(String src);
}

class DartSyntaxPrehighlighter extends SyntaxPrehighlighter {
  DartSyntaxPrehighlighter() {
    _spans = <_HighlightSpan>[];
  }

  static const List<String> _keywords = <String>[
    'abstract',
    'as',
    'assert',
    'async',
    'await',
    'break',
    'case',
    'catch',
    'class',
    'const',
    'continue',
    'default',
    'deferred',
    'do',
    'dynamic',
    'else',
    'enum',
    'export',
    'external',
    'extends',
    'factory',
    'false',
    'final',
    'finally',
    'for',
    'get',
    'if',
    'implements',
    'import',
    'in',
    'is',
    'library',
    'new',
    'null',
    'operator',
    'part',
    'rethrow',
    'return',
    'set',
    'static',
    'super',
    'switch',
    'sync',
    'this',
    'throw',
    'true',
    'try',
    'typedef',
    'var',
    'void',
    'while',
    'with',
    'yield',
  ];

  static const List<String> _builtInTypes = <String>[
    'int',
    'double',
    'num',
    'bool',
  ];

  late String _src;
  late StringScanner _scanner;

  late List<_HighlightSpan> _spans;

  @override
  List<CodeSpan> format(String src) {
    _src = src;
    _scanner = StringScanner(_src);

    if (_generateSpans()) {
      // Successfully parsed the code
      final formattedText = <CodeSpan>[];
      var currentPosition = 0;

      for (final span in _spans) {
        if (currentPosition != span.start) {
          formattedText
              .add(CodeSpan(text: _src.substring(currentPosition, span.start)));
        }

        formattedText
            .add(CodeSpan(type: span.type, text: span.textForSpan(_src)));

        currentPosition = span.end;
      }

      if (currentPosition != _src.length) {
        formattedText
            .add(CodeSpan(text: _src.substring(currentPosition, _src.length)));
      }

      return formattedText;
    } else {
      // Parsing failed, return with only basic formatting
      return [CodeSpan(type: HighlightType.base, text: src)];
    }
  }

  bool _generateSpans() {
    var lastLoopPosition = _scanner.position;

    while (!_scanner.isDone) {
      // Skip White space
      _scanner.scan(RegExp(r'\s+'));

      // Block comments
      if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) {
        _spans.add(_HighlightSpan(
          HighlightType.comment,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // Line comments
      if (_scanner.scan('//')) {
        final startComment = _scanner.lastMatch!.start;

        var eof = false;
        int endComment;
        if (_scanner.scan(RegExp(r'.*\n'))) {
          endComment = _scanner.lastMatch!.end - 1;
        } else {
          eof = true;
          endComment = _src.length;
        }

        _spans.add(_HighlightSpan(
          HighlightType.comment,
          startComment,
          endComment,
        ));

        if (eof) {
          break;
        }

        continue;
      }

      // Raw r"String"
      if (_scanner.scan(RegExp(r'r".*"'))) {
        _spans.add(_HighlightSpan(
          HighlightType.string,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // Raw r'String'
      if (_scanner.scan(RegExp(r"r'.*'"))) {
        _spans.add(_HighlightSpan(
          HighlightType.string,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // Multiline """String"""
      if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
        _spans.add(_HighlightSpan(
          HighlightType.string,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // Multiline '''String'''
      if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
        _spans.add(_HighlightSpan(
          HighlightType.string,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // "String"
      if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) {
        _spans.add(_HighlightSpan(
          HighlightType.string,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // 'String'
      if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) {
        _spans.add(_HighlightSpan(
          HighlightType.string,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // Double
      if (_scanner.scan(RegExp(r'\d+\.\d+'))) {
        _spans.add(_HighlightSpan(
          HighlightType.number,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // Integer
      if (_scanner.scan(RegExp(r'\d+'))) {
        _spans.add(_HighlightSpan(HighlightType.number,
            _scanner.lastMatch!.start, _scanner.lastMatch!.end));
        continue;
      }

      // Punctuation
      if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) {
        _spans.add(_HighlightSpan(
          HighlightType.punctuation,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // Meta data
      if (_scanner.scan(RegExp(r'@\w+'))) {
        _spans.add(_HighlightSpan(
          HighlightType.keyword,
          _scanner.lastMatch!.start,
          _scanner.lastMatch!.end,
        ));
        continue;
      }

      // Words
      if (_scanner.scan(RegExp(r'\w+'))) {
        HighlightType? type;

        var word = _scanner.lastMatch![0]!;
        if (word.startsWith('_')) {
          word = word.substring(1);
        }

        if (_keywords.contains(word)) {
          type = HighlightType.keyword;
        } else if (_builtInTypes.contains(word)) {
          type = HighlightType.keyword;
        } else if (_firstLetterIsUpperCase(word)) {
          type = HighlightType.klass;
        } else if (word.length >= 2 &&
            word.startsWith('k') &&
            _firstLetterIsUpperCase(word.substring(1))) {
          type = HighlightType.constant;
        }

        if (type != null) {
          _spans.add(_HighlightSpan(
            type,
            _scanner.lastMatch!.start,
            _scanner.lastMatch!.end,
          ));
        }
      }

      // Check if this loop did anything
      if (lastLoopPosition == _scanner.position) {
        // Failed to parse this file, abort gracefully
        return false;
      }
      lastLoopPosition = _scanner.position;
    }

    _simplify();
    return true;
  }

  void _simplify() {
    for (var i = _spans.length - 2; i >= 0; i -= 1) {
      if (_spans[i].type == _spans[i + 1].type &&
          _spans[i].end == _spans[i + 1].start) {
        _spans[i] = _HighlightSpan(
          _spans[i].type,
          _spans[i].start,
          _spans[i + 1].end,
        );
        _spans.removeAt(i + 1);
      }
    }
  }

  bool _firstLetterIsUpperCase(String str) {
    if (str.isNotEmpty) {
      final first = str.substring(0, 1);
      return first == first.toUpperCase();
    }
    return false;
  }
}

enum HighlightType {
  number,
  comment,
  keyword,
  string,
  punctuation,
  klass,
  constant,
  base,
}

class _HighlightSpan {
  _HighlightSpan(this.type, this.start, this.end);

  final HighlightType type;
  final int start;
  final int end;

  String textForSpan(String src) {
    return src.substring(start, end);
  }
}

class CodeSpan {
  CodeSpan({
    this.type = HighlightType.base,
    required this.text,
  });

  final HighlightType type;
  final String text;

  @override
  String toString() {
    return 'TextSpan('
        'style: codeStyle.${_styleNameOf(type)}, '
        "text: '${_escape(text)}'"
        ')';
  }
}

String _styleNameOf(HighlightType type) {
  switch (type) {
    case HighlightType.number:
      return 'numberStyle';
    case HighlightType.comment:
      return 'commentStyle';
    case HighlightType.keyword:
      return 'keywordStyle';
    case HighlightType.string:
      return 'stringStyle';
    case HighlightType.punctuation:
      return 'punctuationStyle';
    case HighlightType.klass:
      return 'classStyle';
    case HighlightType.constant:
      return 'constantStyle';
    case HighlightType.base:
      return 'baseStyle';
  }
}

String _escape(String text) {
  final escapedText = StringBuffer();

  for (final char in text.runes) {
    if (char < 0x20 ||
        char >= 0x7F ||
        char == 0x22 ||
        char == 0x24 ||
        char == 0x27 ||
        char == 0x5C) {
      if (char <= 0xffff) {
        escapedText.write('\\u${_encodeAndPad(char)}');
      } else {
        escapedText.write('\\u{${_encode(char)}}');
      }
    } else {
      escapedText.write(String.fromCharCode(char));
    }
  }

  return escapedText.toString();
}

String _encode(int charCode) {
  return charCode.toRadixString(16);
}

String _encodeAndPad(int charCode) {
  final encoded = _encode(charCode);
  return '0' * (4 - encoded.length) + encoded;
}
