// 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 initialize.mirror_loader;

import 'dart:collection' show Queue;
import 'dart:mirrors';
import 'package:path/path.dart' as path;
import 'package:initialize/initialize.dart';

final LibraryMirror _root = currentMirrorSystem().isolate.rootLibrary;
final Map<Uri, LibraryMirror> _libs = currentMirrorSystem().libraries;

Queue<Function> loadInitializers(
    {List<Type> typeFilter, InitializerFilter customFilter, Uri from}) {
  return new InitializationCrawler(typeFilter, customFilter, from: from).run();
}

// Crawls a library and all its dependencies for `Initializer` annotations using
// mirrors
class InitializationCrawler {
  // Set of all visited annotations, keys are the declarations that were
  // annotated, values are the annotations that have been processed.
  static final _annotationsFound =
      new Map<DeclarationMirror, Set<InstanceMirror>>();

  // If non-null, then only these annotations should be processed.
  final List<Type> typeFilter;

  // If non-null, then only annotations which return true when passed to this
  // function will be processed.
  final InitializerFilter customFilter;

  /// The library to start crawling from.
  final LibraryMirror _rootLibrary;

  /// Note: The [from] argument is only supported in the mirror_loader.dart. It
  /// is not supported statically.
  InitializationCrawler(this.typeFilter, this.customFilter, {Uri from})
      : _rootLibrary = from == null
          ? _root
          : _libs[from] {
    if (_rootLibrary == null) throw 'Unable to find library at $from.';
  }

  // The primary function in this class, invoke it to crawl and collect all the
  // annotations into a queue of init functions.
  Queue<Function> run() {
    var librariesSeen = new Set<LibraryMirror>();
    var queue = new Queue<Function>();

    _readLibraryDeclarations(_rootLibrary, librariesSeen, queue);
    return queue;
  }

  /// Returns the canonical [LibraryMirror] for a given [LibraryMirror]. This
  /// is defined as the one loaded from a `package:` url if available, otherwise
  /// it is just [lib].
  LibraryMirror _canonicalLib(LibraryMirror lib) {
    var uri = lib.uri;
    if (_isHttpStylePackageUrl(uri)) {
      var packageUri = _packageUriFor(uri);
      if (_libs.containsKey(packageUri)) return _libs[packageUri];
    }
    return lib;
  }

  /// Returns the canonical [ClassMirror] for a given [ClassMirror]. This is
  /// defined as the one that appears in the canonical owner [LibararyMirror].
  ClassMirror _canonicalClassDeclaration(ClassMirror declaration) =>
      _canonicalLib(declaration.owner).declarations[declaration.simpleName];

  /// Whether [uri] is an http URI that contains a 'packages' segment, and
  /// therefore could be converted into a 'package:' URI.
  bool _isHttpStylePackageUrl(Uri uri) {
    var uriPath = uri.path;
    return uri.scheme == _root.uri.scheme &&
        // Don't process cross-domain uris.
        uri.authority == _root.uri.authority &&
        uriPath.endsWith('.dart') &&
        (uriPath.contains('/packages/') || uriPath.startsWith('packages/'));
  }

  /// Returns a `package:` version of [uri].
  Uri _packageUriFor(Uri uri) {
    var packagePath = uri.path
        .substring(uri.path.lastIndexOf('packages/') + 'packages/'.length);
    return Uri.parse('package:$packagePath');
  }

  // Reads Initializer annotations on this library and all its dependencies in
  // post-order.
  Queue<Function> _readLibraryDeclarations(LibraryMirror lib,
      Set<LibraryMirror> librariesSeen, Queue<Function> queue) {
    lib = _canonicalLib(lib);
    if (librariesSeen.contains(lib)) return queue;
    librariesSeen.add(lib);

    // First visit all our dependencies.
    for (var dependency in lib.libraryDependencies) {
      // Skip dart: imports, they never use this package.
      var targetLibrary = dependency.targetLibrary;
      if (targetLibrary == null || targetLibrary.uri.scheme == 'dart') continue;
      _readLibraryDeclarations(dependency.targetLibrary, librariesSeen, queue);
    }

    // Second parse the library directive annotations.
    _readAnnotations(lib, queue);

    // Last, parse all class and method annotations.
    for (var declaration in _sortedDeclarationsWithMetadata(lib)) {
      _readAnnotations(declaration, queue);
      // Check classes for static annotations which are not supported
      if (declaration is ClassMirror) {
        for (var classDeclaration in declaration.declarations.values) {
          _readAnnotations(classDeclaration, queue);
        }
      }
    }

    return queue;
  }

  Iterable<DeclarationMirror> _sortedDeclarationsWithMetadata(
      LibraryMirror lib) {
    return new List()
      ..addAll(_sortDeclarations(lib, lib.declarations.values
          .where((d) => d is MethodMirror && d.metadata.isNotEmpty)))
      ..addAll(_sortDeclarations(lib, lib.declarations.values
          .where((d) => d is ClassMirror && d.metadata.isNotEmpty)));
  }

  List<DeclarationMirror> _sortDeclarations(
      LibraryMirror sourceLib, Iterable<DeclarationMirror> declarations) {
    var declarationList = declarations.toList();
    declarationList.sort((DeclarationMirror a, DeclarationMirror b) {
      // If in the same file, compare by line.
      var aSourceUri = a.location.sourceUri;
      var bSourceUri = b.location.sourceUri;
      if (aSourceUri == bSourceUri) {
        return a.location.line.compareTo(b.location.line);
      }

      // Run parts first if one is from the original library.
      if (aSourceUri == sourceLib.uri) return 1;
      if (bSourceUri == sourceLib.uri) return -1;

      // Sort parts alphabetically.
      return aSourceUri.path.compareTo(bSourceUri.path);
    });
    return declarationList;
  }

  /// Reads annotations on a [DeclarationMirror] and adds them to [_initQueue]
  /// if they are [Initializer]s.
  void _readAnnotations(DeclarationMirror declaration, Queue<Function> queue) {
    var annotations =
        declaration.metadata.where((m) => _filterMetadata(declaration, m));
    for (var meta in annotations) {
      _annotationsFound.putIfAbsent(
          declaration, () => new Set<InstanceMirror>());
      _annotationsFound[declaration].add(meta);

      // Initialize super classes first, if they are in the same library,
      // otherwise we throw an error. This can only be the case if there are
      // cycles in the imports.
      if (declaration is ClassMirror && declaration.superclass != null) {
        if (declaration.superclass.owner == declaration.owner) {
          _readAnnotations(declaration.superclass, queue);
        } else {
          // Make sure to check the canonical superclass declaration, the one
          // we get here is not always that. Specifically, this occurs if all of
          // the following conditions are met:
          //
          //   1. The current library is never loaded via a `package:` dart
          //      import anywhere in the program.
          //   2. The current library loads the superclass via a relative file
          //      import.
          //   3. The super class is imported via a `package:` import somewhere
          //      else in the program.
          var canonicalSuperDeclaration =
              _canonicalClassDeclaration(declaration.superclass);
          var superMetas = canonicalSuperDeclaration.metadata
              .where((m) => _filterMetadata(canonicalSuperDeclaration, m))
              .toList();
          if (superMetas.isNotEmpty) {
            throw new UnsupportedError(
                'We have detected a cycle in your import graph when running '
                'initializers on ${declaration.qualifiedName}. This means the '
                'super class ${canonicalSuperDeclaration.qualifiedName} has a '
                'dependency on this library (possibly transitive).');
          }
        }
      }

      var annotatedValue;
      if (declaration is ClassMirror) {
        annotatedValue = declaration.reflectedType;
      } else if (declaration is MethodMirror) {
        if (declaration.owner is! LibraryMirror) {
          // TODO(jakemac): Support static class methods.
          throw _TOP_LEVEL_FUNCTIONS_ONLY;
        }
        annotatedValue = (declaration.owner as ObjectMirror)
            .getField(declaration.simpleName).reflectee;
      } else if (declaration is LibraryMirror) {
        var package;
        var filePath;
        Uri uri = declaration.uri;
        // Convert to a package style uri if possible.
        if (_isHttpStylePackageUrl(uri)) {
          uri = _packageUriFor(uri);
        }
        if (uri.scheme == 'file' || uri.scheme.startsWith('http')) {
          filePath = path.url.relative(uri.path,
              from: _root.uri.path.endsWith('/')
                  ? _root.uri.path
                  : path.url.dirname(_root.uri.path));
        } else if (uri.scheme == 'package') {
          var segments = uri.pathSegments;
          package = segments[0];
          filePath = path.url.joinAll(segments.getRange(1, segments.length));
        } else {
          throw new UnsupportedError('Unsupported uri scheme ${uri.scheme} for '
              'library ${declaration}.');
        }
        annotatedValue =
            new LibraryIdentifier(declaration.qualifiedName, package, filePath);
      } else {
        throw _UNSUPPORTED_DECLARATION;
      }
      queue.addLast(() => meta.reflectee.initialize(annotatedValue));
    }
  }

  // Filter function that returns true only if `meta` is an `Initializer`,
  // it passes the `typeFilter` and `customFilter` if they exist, and it has not
  // yet been seen.
  bool _filterMetadata(DeclarationMirror declaration, InstanceMirror meta) {
    if (meta.reflectee is! Initializer) return false;
    if (typeFilter != null &&
        !typeFilter.any((t) => meta.reflectee.runtimeType == t)) {
      return false;
    }
    if (customFilter != null && !customFilter(meta.reflectee)) return false;
    if (!_annotationsFound.containsKey(declaration)) return true;
    if (_annotationsFound[declaration].contains(meta)) return false;
    return true;
  }
}

final _TOP_LEVEL_FUNCTIONS_ONLY = new UnsupportedError(
    'Only top level methods are supported for initializers');

final _UNSUPPORTED_DECLARATION = new UnsupportedError(
    'Initializers are only supported on libraries, classes, and top level '
    'methods');
