// Copyright (c) 2017, 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 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
    hide AnalysisError;
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/folding/folding.dart';
import 'package:analyzer_plugin/utilities/generator.dart';

/// The information about a requested set of folding regions when computing
/// folding regions in a `.dart` file.
///
/// Clients may not extend, implement or mix-in this class.
abstract class DartFoldingRequest implements FoldingRequest {
  /// The analysis result for the file for which the folding regions are being
  /// requested.
  ResolvedUnitResult get result;
}

/// An object that [FoldingContributor]s use to record folding regions.
///
/// Clients may not extend, implement or mix-in this class.
abstract class FoldingCollector {
  /// Record a new folding region corresponding to the given [range] that has the
  /// given [kind].
  void addRange(SourceRange range, FoldingKind kind);

  /// Record a new folding region with the given [offset] and [length] that has
  /// the given [kind].
  void addRegion(int offset, int length, FoldingKind kind);
}

/// An object used to produce folding regions.
///
/// Clients may implement this class when implementing plugins.
abstract class FoldingContributor {
  /// Contribute folding regions into the given [collector].
  void computeFolding(FoldingRequest request, FoldingCollector collector);
}

/// A generator that will generate an 'analysis.folding' notification.
///
/// Clients may not extend, implement or mix-in this class.
class FoldingGenerator {
  /// The contributors to be used to generate the folding regions.
  final List<FoldingContributor> contributors;

  /// Initialize a newly created folding generator to use the given
  /// [contributors].
  FoldingGenerator(this.contributors);

  /// Create an 'analysis.folding' notification. If any of the contributors
  /// throws an exception, also create a non-fatal 'plugin.error' notification.
  GeneratorResult generateFoldingNotification(FoldingRequest request) {
    var notifications = <Notification>[];
    var collector = FoldingCollectorImpl();
    for (var contributor in contributors) {
      try {
        contributor.computeFolding(request, collector);
      } catch (exception, stackTrace) {
        notifications.add(PluginErrorParams(
                false, exception.toString(), stackTrace.toString())
            .toNotification());
      }
    }
    notifications.add(AnalysisFoldingParams(request.path, collector.regions)
        .toNotification());
    return GeneratorResult(null, notifications);
  }
}

/// The information about a requested set of folding regions.
///
/// Clients may not extend, implement or mix-in this class.
abstract class FoldingRequest {
  /// Return the path of the file for which folding regions are being requested.
  String get path;

  /// Return the resource provider associated with this request.
  ResourceProvider get resourceProvider;
}
