// Copyright (c) 2015, 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.

/// A library to generate Dart source code.
library src_gen_dart;

import '../common/src_gen_common.dart';

/// A class used to generate Dart source code. This class facilitates writing out
/// dartdoc comments, automatically manages indent by counting curly braces, and
/// automatically wraps doc comments on 80 char column boundaries.
class DartGenerator {
  static const defaultColumnBoundary = 80;

  final int colBoundary;
  final String interfaceName;

  String _indent = '';
  final StringBuffer _buf = StringBuffer();

  bool _previousWasEol = false;

  DartGenerator({
    required this.interfaceName,
    this.colBoundary = defaultColumnBoundary,
  });

  /// Write out the given dartdoc text, wrapping lines as necessary to flow
  /// along the column boundary.
  void writeDocs(String docs) {
    docs = docs
        .replaceAll('[RPC error] code', 'RPC error code')
        .replaceAll('[RPC error]', '[RPCError]')
        .replaceAll('[SnapshotGraph]', '[HeapSnapshotGraph]')
        .replaceAllMapped(RegExp(r'\[([gs]et[a-zA-Z]+)\]'), (match) {
      return '[$interfaceName.${match[1]}]';
    });

    docs = wrap(docs.trim(), colBoundary - _indent.length - 4);
    // docs = docs.replaceAll('*/', '/');
    // docs = docs.replaceAll('/*', r'/\*');

    docs.split('\n').forEach((line) => _writeln('/// $line'.trimRight()));

    // if (!docs.contains('\n') && preferSingle) {
    //   _writeln("/// ${docs}", true);
    // } else {
    //   _writeln("/**", true);
    //   _writeln(" * ${docs.replaceAll("\n", "\n * ")}", true);
    //   _writeln(" */", true);
    // }
  }

  /// Write out the given Dart statement and terminate it with an eol. If the
  /// statement will overflow the column boundary, attempt to wrap it at
  /// reasonable places.
  void writeStatement(String str) {
    if (_indent.length + str.length > colBoundary) {
      // Split the line on the first '('. Currently, we don't do anything
      // fancier then that. This takes the edge off the long lines.
      int index = str.indexOf('(');

      if (index == -1) {
        writeln(str);
      } else {
        writeln(str.substring(0, index + 1));
        writeln('    ${str.substring(index + 1)}');
      }
    } else {
      writeln(str);
    }
  }

  void writeln([String str = '']) => _write('$str\n');

  void write(String str) => _write(str);

  void out(String str) => _buf.write(str);

  void _writeln([String str = '', bool ignoreCurlies = false]) =>
      _write('$str\n', ignoreCurlies);

  void _write(String str, [bool ignoreCurlies = false]) {
    for (final int rune in str.runes) {
      if (!ignoreCurlies) {
        if (rune == $leftCurly) {
          _indent = '$_indent  ';
        } else if (rune == $rightCurly && _indent.length >= 2) {
          _indent = _indent.substring(2);
        }
      }

      if (_previousWasEol && rune != $eol) {
        _buf.write(_indent);
      }

      _buf.write(String.fromCharCode(rune));

      _previousWasEol = rune == $eol;
    }
  }

  @override
  String toString() => _buf.toString();
}
