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

import 'dart:async';
import 'dart:io';

import 'package:package_config/packages_file.dart' as packages_file;
import 'package:path/path.dart' as p;

/// [Resolver] resolves imports with respect to a given environment.
class Resolver {
  Resolver({String packagesPath, this.packageRoot, this.sdkRoot})
      : packagesPath = packagesPath,
        _packages = packagesPath != null ? _parsePackages(packagesPath) : null;

  final String packagesPath;
  final String packageRoot;
  final String sdkRoot;
  final List<String> failed = [];
  final Map<String, Uri> _packages;

  /// Returns the absolute path wrt. to the given environment or null, if the
  /// import could not be resolved.
  String resolve(String scriptUri) {
    final uri = Uri.parse(scriptUri);
    if (uri.scheme == 'dart') {
      if (sdkRoot == null) {
        // No sdk-root given, do not resolve dart: URIs.
        return null;
      }
      String filePath;
      if (uri.pathSegments.length > 1) {
        var path = uri.pathSegments[0];
        // Drop patch files, since we don't have their source in the compiled
        // SDK.
        if (path.endsWith('-patch')) {
          failed.add('$uri');
          return null;
        }
        // Canonicalize path. For instance: _collection-dev => _collection_dev.
        path = path.replaceAll('-', '_');
        final pathSegments = [
          sdkRoot,
          path,
          ...uri.pathSegments.sublist(1),
        ];
        filePath = p.joinAll(pathSegments);
      } else {
        // Resolve 'dart:something' to be something/something.dart in the SDK.
        final lib = uri.path;
        filePath = p.join(sdkRoot, lib, '$lib.dart');
      }
      return resolveSymbolicLinks(filePath);
    }
    if (uri.scheme == 'package') {
      if (packagesPath == null && packageRoot == null) {
        // No package-root given, do not resolve package: URIs.
        return null;
      }

      final packageName = uri.pathSegments[0];
      if (_packages != null) {
        final packageUri = _packages[packageName];
        if (packageUri == null) {
          failed.add('$uri');
          return null;
        }
        final packagePath = p.fromUri(packageUri);
        final pathInPackage = p.joinAll(uri.pathSegments.sublist(1));
        return resolveSymbolicLinks(p.join(packagePath, pathInPackage));
      }
      return resolveSymbolicLinks(p.join(packageRoot, uri.path));
    }
    if (uri.scheme == 'file') {
      return resolveSymbolicLinks(p.fromUri(uri));
    }
    // We cannot deal with anything else.
    failed.add('$uri');
    return null;
  }

  /// Returns a canonicalized path, or `null` if the path cannot be resolved.
  String resolveSymbolicLinks(String path) {
    final normalizedPath = p.normalize(path);
    final type = FileSystemEntity.typeSync(normalizedPath, followLinks: true);
    if (type == FileSystemEntityType.notFound) return null;
    return File(normalizedPath).resolveSymbolicLinksSync();
  }

  static Map<String, Uri> _parsePackages(String packagesPath) {
    final source = File(packagesPath).readAsBytesSync();
    return packages_file.parse(source, Uri.file(packagesPath));
  }
}

/// Bazel URI resolver.
class BazelResolver extends Resolver {
  /// Creates a Bazel resolver with the specified workspace path, if any.
  BazelResolver({this.workspacePath = ''});

  final String workspacePath;

  /// Returns the absolute path wrt. to the given environment or null, if the
  /// import could not be resolved.
  @override
  String resolve(String scriptUri) {
    final uri = Uri.parse(scriptUri);
    if (uri.scheme == 'dart') {
      // Ignore the SDK
      return null;
    }
    if (uri.scheme == 'package') {
      // TODO(cbracken) belongs in a Bazel package
      return _resolveBazelPackage(uri.pathSegments);
    }
    if (uri.scheme == 'file') {
      final runfilesPathSegment =
          '.runfiles/$workspacePath'.replaceAll(RegExp(r'/*$'), '/');
      final runfilesPos = uri.path.indexOf(runfilesPathSegment);
      if (runfilesPos >= 0) {
        final pathStart = runfilesPos + runfilesPathSegment.length;
        return uri.path.substring(pathStart);
      }
      return null;
    }
    if (uri.scheme == 'https' || uri.scheme == 'http') {
      return _extractHttpPath(uri);
    }
    // We cannot deal with anything else.
    failed.add('$uri');
    return null;
  }

  String _extractHttpPath(Uri uri) {
    final packagesPos = uri.pathSegments.indexOf('packages');
    if (packagesPos >= 0) {
      final workspacePath = uri.pathSegments.sublist(packagesPos + 1);
      return _resolveBazelPackage(workspacePath);
    }
    return uri.pathSegments.join('/');
  }

  String _resolveBazelPackage(List<String> pathSegments) {
    // TODO(cbracken) belongs in a Bazel package
    final packageName = pathSegments[0];
    final pathInPackage = pathSegments.sublist(1).join('/');
    final packagePath = packageName.contains('.')
        ? packageName.replaceAll('.', '/')
        : 'third_party/dart/$packageName';
    return '$packagePath/lib/$pathInPackage';
  }
}

/// Loads the lines of imported resources.
class Loader {
  final List<String> failed = [];

  /// Loads an imported resource and returns a [Future] with a [List] of lines.
  /// Returns `null` if the resource could not be loaded.
  Future<List<String>> load(String path) async {
    try {
      // Ensure `readAsLines` runs within the try block so errors are caught.
      return await File(path).readAsLines();
    } catch (_) {
      failed.add(path);
      return null;
    }
  }
}
