// 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));
    }
  }
}
