// 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 list of "clauses" where each clause starts with a keyword and has a
/// comma-separated list of items under it.
///
/// Used for `show` and `hide` combinators in import and export directives, and
/// `extends`, `implements`, and `with` clauses in type declarations.
///
/// Clauses can be chained on one line if they all fit, like:
///
///     import 'animals.dart' show Ant, Bat hide Cat, Dog;
///
/// Or can split before all of the clauses, like:
///
///     import 'animals.dart'
///         show Ant, Bat
///         hide Cat, Dog;
///
/// They can also split before every item in any of the clauses. If they do so,
/// then the clauses must split too. So these are allowed:
///
///     import 'animals.dart'
///         show
///             Ant,
///             Bat
///         hide Cat, Dog;
///
///     import 'animals.dart'
///         show Ant, Bat
///         hide
///             Cat,
///             Dog;
///
///     import 'animals.dart'
///         show
///             Ant,
///             Bat
///         hide
///             Cat,
///             Dog;
///
/// But these are not:
///
///     // Wrap list but not keyword:
///     import 'animals.dart' show
///             Ant,
///             Bat
///         hide Cat, Dog;
///
///     // Wrap one keyword but not both:
///     import 'animals.dart'
///         show Ant, Bat hide Cat, Dog;
///
///     import 'animals.dart' show Ant, Bat
///         hide Cat, Dog;
///
/// This ensures that when any wrapping occurs, the keywords are always at the
/// beginning of the line.
final class ClausePiece(
  /// The leading construct the clauses are applied to: a class declaration,
  /// import directive, etc.
  final Piece _header,
  final List<Piece> _clauses, {
  bool allowLeadingClause = false,
}) extends Piece {
  /// State where we split between the clauses but not before the first one.
  static const State _betweenClauses = State(1);

  /// If `true`, then we're allowed to split between the clauses without
  /// splitting before the first one too.
  ///
  /// This is used for class declarations where the `extends` clauses is treated
  /// a little specially because it's a deeper coupling to the class and so we
  /// want it to stay on the top line even if the other clauses split, like:
  ///
  ///     class BaseClass extends Derived
  ///         implements OtherThing {
  ///       ...
  ///     }
  final bool _allowLeadingClause = allowLeadingClause && _clauses.length > 1;

  @override
  List<State> get additionalStates => [
    if (_allowLeadingClause) _betweenClauses,
    State.split,
  ];

  @override
  Set<Shape> allowedChildShapes(State state, Piece child) {
    if (child == _header) {
      // If the header splits, force the clauses to split too.
      return Shape.anyIf(state == State.split);
    } else if (_allowLeadingClause && child == _clauses.first) {
      // A split inside the first clause forces a split before the keyword.
      return Shape.anyIf(state == State.split);
    } else {
      // For the other clauses (or if there is no leading one), any split
      // inside a clause forces all of them to split.
      return Shape.anyIf(state != State.unsplit);
    }
  }

  @override
  void format(CodeWriter writer, State state) {
    writer.format(_header);

    writer.pushIndent(Indent.expression);

    for (var clause in _clauses) {
      if (_allowLeadingClause && clause == _clauses.first) {
        // Before the leading clause, only split when in the fully split state.
        // A split inside the first clause forces a split before the keyword.
        writer.splitIf(state == State.split);
        writer.format(clause);
      } else {
        // For the other clauses (or if there is no leading one), split in the
        // fully split state and any split inside and clause forces all of them
        // to split.
        writer.splitIf(state != State.unsplit);
        writer.format(clause);
      }
    }

    writer.popIndent();
  }

  @override
  void forEachChild(void Function(Piece piece) callback) {
    callback(_header);
    _clauses.forEach(callback);
  }
}
