// 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 DEFAULT_COLUMN_BOUNDARY = 80;

  final int colBoundary;

  String _indent = "";
  final StringBuffer _buf = new StringBuffer();

  bool _previousWasEol = false;

  DartGenerator({this.colBoundary = DEFAULT_COLUMN_BOUNDARY});

  /// Write out the given dartdoc text, wrapping lines as necessary to flow
  /// along the column boundary. If [preferSingle] is true, and the docs would
  /// fit on a single line, use `///` dartdoc style.
  void writeDocs(String docs) {
    if (docs == null) return;

    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 == RUNE_LEFT_CURLY) {
          _indent = "${_indent}  ";
        } else if (rune == RUNE_RIGHT_CURLY && _indent.length >= 2) {
          _indent = _indent.substring(2);
        }
      }

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

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

      _previousWasEol = rune == RUNE_EOL;
    }
  }

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