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

library services.dependencies.library;

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';

class LibraryDependencyCollector {
  final Set<LibraryElement> _visitedLibraries = new Set<LibraryElement>();
  final Set<String> _dependencies = new Set<String>();

  final List<AnalysisContext> _contexts;

  LibraryDependencyCollector(this._contexts);

  Map<String, Map<String, List<String>>> calculatePackageMap(
      Map<Folder, AnalysisContext> folderMap) {
    Map<AnalysisContext, Folder> contextMap = _reverse(folderMap);
    Map<String, Map<String, List<String>>> result =
        new Map<String, Map<String, List<String>>>();
    for (AnalysisContext context in _contexts) {
      Map<String, List<Folder>> packageMap = context.sourceFactory.packageMap;
      if (packageMap != null) {
        Map<String, List<String>> map = new Map<String, List<String>>();
        packageMap.forEach((String name, List<Folder> folders) =>
            map[name] = new List.from(folders.map((Folder f) => f.path)));
        result[contextMap[context].path] = map;
      }
    }
    return result;
  }

  Set<String> collectLibraryDependencies() {
    _contexts.forEach((AnalysisContext context) => context.librarySources
        .forEach((Source source) =>
            _addDependencies(context.getLibraryElement(source))));
    return _dependencies;
  }

  Map<AnalysisContext, Folder> _reverse(Map<Folder, AnalysisContext> map) {
    Map<AnalysisContext, Folder> reverseMap =
        new Map<AnalysisContext, Folder>();
    map.forEach((Folder f, AnalysisContext c) => reverseMap[c] = f);
    return reverseMap;
  }

  void _addDependencies(LibraryElement libraryElement) {
    if (libraryElement == null) {
      return;
    }
    if (_visitedLibraries.add(libraryElement)) {
      for (CompilationUnitElement cu in libraryElement.units) {
        String path = cu.source.fullName;
        if (path != null) {
          _dependencies.add(path);
        }
      }
      libraryElement.imports.forEach(
          (ImportElement import) => _addDependencies(import.importedLibrary));
      libraryElement.exports.forEach(
          (ExportElement export) => _addDependencies(export.exportedLibrary));
    }
  }
}
