// Copyright (c) 2023, 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.
import '../back_end/code_writer.dart';
import 'piece.dart';

/// A constructor declaration.
///
/// This is somewhat similar to [FunctionPiece], but constructor initializers
/// add a lot of complexity. In particular, there are constraints between how
/// the parameter list is allowed to split and how the initializer list is
/// allowed to split. Only a few combinations of splits are allowed:
///
/// [State.unsplit] No splits at all, in the parameters or initializers.
///
/// ```
///   SomeClass(param) : a = 1, b = 2;
/// ```
///
/// [_splitBeforeInitializers] Split before the `:` and between the
/// initializers but not in the parameters.
///
/// ```
///   SomeClass(param)
///     : a = 1,
///       b = 2;
/// ```
///
/// [_splitBetweenInitializers] Split between the initializers but not before
/// the `:`. This state should only be chosen when the parameters split. If
/// there are no parameters, this state is excluded.
///
/// ```
///   SomeClass(
///     param
///   ) : a = 1,
///       b = 2;
/// ```
///
/// In addition, this piece deals with indenting initializers appropriately
/// based on whether the parameter list has a `]` or `}` before the `)`. If
/// there are optional parameters, then initializers after the first are
/// indented one space more to line up with the first initializer:
///
/// ```
/// SomeClass(
///   mandatory,
/// ) : firstInitializer = 1,
///     second = 2;
/// // ^ Four spaces of indentation.
///
/// SomeClass([
///   optional,
/// ]) : firstInitializer = 1,
///      second = 2;
/// //  ^ Five spaces of indentation.
/// ```
class ConstructorPiece extends Piece {
  static const _splitBeforeInitializers = State(1, cost: 1);

  static const _splitBetweenInitializers = State(2, cost: 2);

  /// True if there are parameters or comments inside the parameter list.
  ///
  /// If so, then we allow splitting the parameter list while leaving the `:`
  /// on the same line as the `)`.
  final bool _canSplitParameters;

  /// Whether the parameter list contains a `]` or `}` closing delimiter before
  /// the `)`.
  final bool _hasOptionalParameter;

  /// The leading keywords, class name, and constructor name.
  final Piece _header;

  /// The constructor parameter list.
  final Piece _parameters;

  /// If this is a redirecting constructor, the redirection clause.
  final Piece? _redirect;

  /// If there are initializers, the `:` before them.
  final Piece? _initializerSeparator;

  /// The constructor initializers, if there are any.
  final Piece? _initializers;

  /// The constructor body.
  final Piece _body;

  ConstructorPiece(this._header, this._parameters, this._body,
      {required bool canSplitParameters,
      required bool hasOptionalParameter,
      Piece? redirect,
      Piece? initializerSeparator,
      Piece? initializers})
      : _canSplitParameters = canSplitParameters,
        _hasOptionalParameter = hasOptionalParameter,
        _redirect = redirect,
        _initializerSeparator = initializerSeparator,
        _initializers = initializers;

  @override
  List<State> get additionalStates => [
        if (_initializers != null) _splitBeforeInitializers,
        if (_canSplitParameters && _initializers != null)
          _splitBetweenInitializers
      ];

  @override
  void format(CodeWriter writer, State state) {
    // There are constraints between how the parameters may split and now the
    // initializers may split.
    var (parameterState, initializerState) = switch (state) {
      // If there are no initializers, the parameters can do whatever.
      State.unsplit when _initializers == null => (null, null),
      // All parameters and initializers on one line.
      State.unsplit => (State.unsplit, State.unsplit),
      // If the `:` splits, then the parameters can't.
      _splitBeforeInitializers => (State.unsplit, State.split),
      // The `) :` on its own line.
      _splitBetweenInitializers => (State.split, State.split),
      _ => throw ArgumentError(),
    };

    // If there's a newline in the header or parameters (like a line comment
    // after the `)`), then don't allow the initializers to remain unsplit.
    if (_initializers != null && state == State.unsplit) {
      writer.setAllowNewlines(false);
    }

    writer.format(_header);
    writer.format(_parameters, requireState: parameterState);

    if (_redirect case var redirect?) {
      writer.space();
      writer.format(redirect);
    }

    if (_initializers case var initializers?) {
      writer.setAllowNewlines(state != State.unsplit);
      writer.splitIf(state == _splitBeforeInitializers, indent: 2);

      writer.format(_initializerSeparator!);
      writer.space();

      // Indent subsequent initializers past the `:`.
      if (_hasOptionalParameter && state == _splitBetweenInitializers) {
        // If the parameter list ends in `]) : init...` then we need to indent
        // +5 to line up subsequent initializers.
        writer.setIndent(5);
      } else {
        writer.setIndent(4);
      }

      writer.format(initializers, requireState: initializerState);
    }

    writer.setIndent(0);
    writer.setAllowNewlines(true);
    writer.format(_body);
  }

  @override
  void forEachChild(void Function(Piece piece) callback) {
    callback(_header);
    callback(_parameters);
    if (_redirect case var redirect?) callback(redirect);
    if (_initializerSeparator case var separator?) callback(separator);
    if (_initializers case var initializers?) callback(initializers);
    callback(_body);
  }

  @override
  String get debugName => 'Ctor';
}
