// Copyright (c) 2019, 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.

/// Looks for ".dart" files in "tests/" that appear to be orphaned. That means
/// they don't end in "_test.dart" so aren't run as tests by the test_runner,
/// but they also don't appear to be referenced by any other tests.
///
/// Usually this means that someone accidentally left off the "_test" and the
/// file is supposed to be a test but is silently getting ignored.
import 'dart:io';

import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_builder.dart';
import 'package:analyzer/dart/analysis/context_locator.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';

import 'package:test_runner/src/path.dart';

AnalysisContext _analysisContext;

void main(List<String> arguments) {
  _initAnalysisContext();

  var suites = Directory('tests').listSync();
  suites.sort((a, b) => a.path.compareTo(b.path));

  for (var entry in suites) {
    // Skip the co19 tests since they don't use '_test.dart'.
    if (entry is Directory && !entry.path.contains('co19')) {
      _checkTestDirectory(entry);
    }
  }
}

void _initAnalysisContext() {
  var roots = ContextLocator().locateRoots(includedPaths: ['test']);
  if (roots.length != 1) {
    throw StateError('Expected to find exactly one context root, got $roots');
  }

  _analysisContext = ContextBuilder().createContext(contextRoot: roots[0]);
}

void _checkTestDirectory(Directory directory) {
  print('-- ${directory.path} --');
  var paths = directory
      .listSync(recursive: true)
      .map((entry) => entry.path)
      .where((path) => path.endsWith('.dart'))
      .toList();
  paths.sort();

  // Collect the set of all files that are known to be referred to by others.
  print('Finding referenced files...');
  var importedPaths = <String>{};
  for (var path in paths) {
    _parseReferences(importedPaths, path);
  }

  // Find the ".dart" files that don't end in "_test.dart" but also aren't used
  // by another library. Those should probably be tests.
  var hasOrphan = false;
  for (var path in paths) {
    if (!path.endsWith('_test.dart') && !importedPaths.contains(path)) {
      print('Suspected orphan: $path');
      hasOrphan = true;
    }
  }

  if (!hasOrphan) print('No orphans :)');
}

void _parseReferences(Set<String> importedPaths, String filePath) {
  var absolute = Path(filePath).absolute.toNativePath();
  var parseResult = _analysisContext.currentSession.getParsedUnit(absolute);
  var unit = (parseResult as ParsedUnitResult).unit;

  void add(String importPath) {
    if (importPath.startsWith('dart:')) return;

    var resolved = Uri.file(filePath).resolve(importPath).path;
    importedPaths.add(resolved);
  }

  for (var directive in unit.directives) {
    if (directive is UriBasedDirective) {
      add(directive.uri.stringValue);
    }
  }
}
