// Copyright 2014 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 'package:flutter/material.dart';
import 'package:string_scanner/string_scanner.dart';

class SyntaxHighlighterStyle {
  SyntaxHighlighterStyle({
    this.baseStyle,
    this.numberStyle,
    this.commentStyle,
    this.keywordStyle,
    this.stringStyle,
    this.punctuationStyle,
    this.classStyle,
    this.constantStyle,
  });

  static SyntaxHighlighterStyle lightThemeStyle() {
    return SyntaxHighlighterStyle(
      baseStyle: const TextStyle(color: Color(0xFF000000)),
      numberStyle: const TextStyle(color: Color(0xFF1565C0)),
      commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
      keywordStyle: const TextStyle(color: Color(0xFF9C27B0)),
      stringStyle: const TextStyle(color: Color(0xFF43A047)),
      punctuationStyle: const TextStyle(color: Color(0xFF000000)),
      classStyle: const TextStyle(color: Color(0xFF512DA8)),
      constantStyle: const TextStyle(color: Color(0xFF795548)),
    );
  }

  static SyntaxHighlighterStyle darkThemeStyle() {
    return SyntaxHighlighterStyle(
      baseStyle: const TextStyle(color: Color(0xFFFFFFFF)),
      numberStyle: const TextStyle(color: Color(0xFF1565C0)),
      commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
      keywordStyle: const TextStyle(color: Color(0xFF80CBC4)),
      stringStyle: const TextStyle(color: Color(0xFF009688)),
      punctuationStyle: const TextStyle(color: Color(0xFFFFFFFF)),
      classStyle: const TextStyle(color: Color(0xFF009688)),
      constantStyle: const TextStyle(color: Color(0xFF795548)),
    );
  }

  final TextStyle? baseStyle;
  final TextStyle? numberStyle;
  final TextStyle? commentStyle;
  final TextStyle? keywordStyle;
  final TextStyle? stringStyle;
  final TextStyle? punctuationStyle;
  final TextStyle? classStyle;
  final TextStyle? constantStyle;
}

abstract class SyntaxHighlighter {
  TextSpan format(String src);
}

class DartSyntaxHighlighter extends SyntaxHighlighter {
  DartSyntaxHighlighter([this._style]) {
    _spans = <_HighlightSpan>[];
    _style ??= SyntaxHighlighterStyle.darkThemeStyle();
  }

  SyntaxHighlighterStyle? _style;

  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',
  ];

  String? _src;
  late StringScanner _scanner;

  late List<_HighlightSpan> _spans;

  @override
  TextSpan format(String? src) {
    _src = src;
    _scanner = StringScanner(_src!);

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

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

        formattedText.add(TextSpan(style: span.textStyle(_style), text: span.textForSpan(_src!)));

        currentPosition = span.end;
      }

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

      return TextSpan(style: _style!.baseStyle, children: formattedText);
    } else {
      // Parsing failed, return with only basic formatting
      return TextSpan(style: _style!.baseStyle, text: src);
    }
  }

  bool _generateSpans() {
    int 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 int startComment = _scanner.lastMatch!.start;

        bool 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;

        String 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 (int 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 String first = str.substring(0, 1);
      return first == first.toUpperCase();
    }
    return false;
  }
}

enum _HighlightType {
  number,
  comment,
  keyword,
  string,
  punctuation,
  klass,
  constant
}

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);
  }

  TextStyle? textStyle(SyntaxHighlighterStyle? style) {
    if (type == _HighlightType.number) {
      return style!.numberStyle;
    } else if (type == _HighlightType.comment) {
      return style!.commentStyle;
    } else if (type == _HighlightType.keyword) {
      return style!.keywordStyle;
    } else if (type == _HighlightType.string) {
      return style!.stringStyle;
    } else if (type == _HighlightType.punctuation) {
      return style!.punctuationStyle;
    } else if (type == _HighlightType.klass) {
      return style!.classStyle;
    } else if (type == _HighlightType.constant) {
      return style!.constantStyle;
    } else {
      return style!.baseStyle;
    }
  }
}
