// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io' show Directory;

import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:path/path.dart' as path;

import '../utils.dart';

/// Analyzes the dart source files in the given `flutterRootDirectory` with the
/// given [AnalyzeRule]s.
///
/// The `includePath` parameter takes a collection of paths relative to the given
/// `flutterRootDirectory`. It specifies the files or directory this function
/// should analyze. Defaults to null in which case this function analyzes the
/// all dart source files in `flutterRootDirectory`.
///
/// The `excludePath` parameter takes a collection of paths relative to the given
/// `flutterRootDirectory` that this function should skip analyzing.
///
/// If a compilation unit can not be resolved, this function ignores the
/// corresponding dart source file and logs an error using [foundError].
Future<void> analyzeWithRules(
  String flutterRootDirectory,
  List<AnalyzeRule> rules, {
  Iterable<String>? includePaths,
  Iterable<String>? excludePaths,
}) async {
  if (!Directory(flutterRootDirectory).existsSync()) {
    foundError(<String>['Analyzer error: the specified $flutterRootDirectory does not exist.']);
  }
  final Iterable<String> includes =
      includePaths?.map(
        (String relativePath) => path.canonicalize('$flutterRootDirectory/$relativePath'),
      ) ??
      <String>[path.canonicalize(flutterRootDirectory)];
  final AnalysisContextCollection collection = AnalysisContextCollection(
    includedPaths: includes.toList(),
    excludedPaths: excludePaths
        ?.map((String relativePath) => path.canonicalize('$flutterRootDirectory/$relativePath'))
        .toList(),
  );

  final List<String> analyzerErrors = <String>[];
  for (final AnalysisContext context in collection.contexts) {
    final Iterable<String> analyzedFilePaths = context.contextRoot.analyzedFiles();
    final AnalysisSession session = context.currentSession;

    for (final String filePath in analyzedFilePaths) {
      final SomeResolvedUnitResult unit = await session.getResolvedUnit(filePath);
      if (unit is ResolvedUnitResult) {
        for (final AnalyzeRule rule in rules) {
          rule.applyTo(unit);
        }
      } else {
        analyzerErrors.add(
          'Analyzer error: file $unit could not be resolved. Expected "ResolvedUnitResult", got ${unit.runtimeType}.',
        );
      }
    }
  }

  if (analyzerErrors.isNotEmpty) {
    foundError(analyzerErrors);
  }
  for (final AnalyzeRule verifier in rules) {
    verifier.reportViolations(flutterRootDirectory);
  }
}

/// An interface that defines a set of best practices, and collects information
/// about code that violates the best practices in a [ResolvedUnitResult].
///
/// The [analyzeWithRules] function scans and analyzes the specified
/// source directory using the dart analyzer package, and applies custom rules
/// defined in the form of this interface on each resulting [ResolvedUnitResult].
/// The [reportViolations] method will be called at the end, once all
/// [ResolvedUnitResult]s are parsed.
///
/// Implementers can assume each [ResolvedUnitResult] is valid compilable dart
/// code, as the caller only applies the custom rules once the code passes
/// `flutter analyze`.
abstract class AnalyzeRule {
  /// Applies this rule to the given [ResolvedUnitResult] (typically a file), and
  /// collects information about violations occurred in the compilation unit.
  void applyTo(ResolvedUnitResult unit);

  /// Reports all violations in the resolved compilation units [applyTo] was
  /// called on, if any.
  ///
  /// This method is called once all [ResolvedUnitResult] are parsed.
  ///
  /// The implementation typically calls [foundErrors] to report violations.
  void reportViolations(String workingDirectory);
}
