// 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 source.sdk_ext;

import 'dart:convert';
import 'dart:core' hide Resource;

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
import 'package:path/path.dart' as pathos;

/// Given a packageMap (see [PackageMapProvider]), check in each package's lib
/// directory for the existence of a `_sdkext` file. This file must contain a
/// JSON encoded map. Each key in the map is a `dart:` library name. Each value
/// is a path (relative to the directory containing `_sdkext`) to a dart script
/// for the given library. For example:
/// {
///   "dart:sky": "../sdk_ext/dart_sky.dart"
/// }
///
/// If a key doesn't begin with `dart:` it is ignored.
class SdkExtUriResolver extends UriResolver {
  static const String SDK_EXT_NAME = '_sdkext';
  static const String DART_COLON_PREFIX = 'dart:';

  final Map<String, String> _urlMappings = <String, String>{};

  /// Construct a [SdkExtUriResolver] from a package map
  /// (see [PackageMapProvider]).
  SdkExtUriResolver(Map<String, List<Folder>> packageMap) {
    if (packageMap == null) {
      return;
    }
    packageMap.forEach(_processPackage);
  }

  /// Number of sdk extensions.
  int get length => _urlMappings.length;

  /// Return the path mapping for [libName] or null if there is none.
  String operator [](String libName) => _urlMappings[libName];

  /// Programmatically add a new SDK extension given a JSON description
  /// ([sdkExtJSON]) and a lib directory ([libDir]).
  void addSdkExt(String sdkExtJSON, Folder libDir) {
    _processSdkExt(sdkExtJSON, libDir);
  }

  @override
  Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
    String libraryName = _libraryName(importUri);
    String partPath = _partPath(importUri);
    // Lookup library name in mappings.
    String mapping = _urlMappings[libraryName];
    if (mapping == null) {
      // Not found.
      return null;
    }
    // This mapping points to the main entry file of the sdk extension.
    Uri libraryEntry = new Uri.file(mapping);
    if (!libraryEntry.isAbsolute) {
      // We expect an absolute path.
      return null;
    }

    if (partPath != null) {
      return _resolvePart(libraryEntry, partPath, importUri);
    } else {
      return _resolveEntry(libraryEntry, importUri);
    }
  }

  @override
  Uri restoreAbsolute(Source source) {
    String extensionName = _findExtensionNameFor(source.fullName);
    if (extensionName != null) {
      return Uri.parse(extensionName);
    }
    // TODO(johnmccutchan): Handle restoring parts.
    return null;
  }

  /// Return the extension name for [fullName] or `null`.
  String _findExtensionNameFor(String fullName) {
    var result;
    _urlMappings.forEach((extensionName, pathMapping) {
      if (pathMapping == fullName) {
        result = extensionName;
      }
    });
    return result;
  }

  /// Return the library name of [importUri].
  String _libraryName(Uri importUri) {
    var uri = importUri.toString();
    int index = uri.indexOf('/');
    if (index >= 0) {
      return uri.substring(0, index);
    }
    return uri;
  }

  /// Return the part path of [importUri].
  String _partPath(Uri importUri) {
    var uri = importUri.toString();
    int index = uri.indexOf('/');
    if (index >= 0) {
      return uri.substring(index + 1);
    }
    return null;
  }

  /// Given a package [name] and a list of folders ([libDirs]),
  /// add any found sdk extensions.
  void _processPackage(String name, List<Folder> libDirs) {
    for (var libDir in libDirs) {
      var sdkExt = _readDotSdkExt(libDir);
      if (sdkExt != null) {
        _processSdkExt(sdkExt, libDir);
      }
    }
  }

  /// Given the JSON for an SDK extension ([sdkExtJSON]) and a folder
  /// ([libDir]), setup the uri mapping.
  void _processSdkExt(String sdkExtJSON, Folder libDir) {
    var sdkExt;
    try {
      sdkExt = JSON.decode(sdkExtJSON);
    } catch (e) {
      return;
    }
    if ((sdkExt == null) || (sdkExt is! Map)) {
      return;
    }
    sdkExt.forEach((k, v) => _processSdkExtension(k, v, libDir));
  }

  /// Install the mapping from [name] to [libDir]/[file].
  void _processSdkExtension(String name, String file, Folder libDir) {
    if (!name.startsWith(DART_COLON_PREFIX)) {
      // SDK extensions must begin with 'dart:'.
      return;
    }
    var key = name;
    var value = libDir.canonicalizePath(file);
    _urlMappings[key] = value;
  }

  /// Read the contents of [libDir]/[SDK_EXT_NAME] as a string.
  /// Returns null if the file doesn't exist.
  String _readDotSdkExt(Folder libDir) {
    var file = libDir.getChild(SDK_EXT_NAME);
    try {
      return file.readAsStringSync();
    } on FileSystemException {
      // File can't be read.
      return null;
    }
  }

  /// Resolve an import of an sdk extension.
  Source _resolveEntry(Uri libraryEntry, Uri importUri) {
    // Library entry.
    JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
    return new FileBasedSource(javaFile, importUri);
  }

  /// Resolve a 'part' statement inside an sdk extension.
  Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
    // Library part.
    var directory = pathos.dirname(libraryEntry.path);
    var partUri = new Uri.file(pathos.join(directory, partPath));
    assert(partUri.isAbsolute);
    JavaFile javaFile = new JavaFile.fromUri(partUri);
    return new FileBasedSource(javaFile, importUri);
  }
}
