// Copyright (c) 2017, 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:collection';
import 'dart:core';

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/util/uri.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart';
import 'package:package_config/src/packages_impl.dart';
import 'package:path/path.dart' as path;

/**
 * Information about a Gn workspace.
 */
class GnWorkspace extends Workspace {
  /**
   * The name of the directory that identifies the root of the workspace.
   */
  static const String _jiriRootName = '.jiri_root';

  /**
   * The name of the file that identifies a set of GN Targets.
   *
   * For Dart package purposes, a BUILD.gn file identifies a package.
   */
  static const String _buildFileName = 'BUILD.gn';

  /**
   * The resource provider used to access the file system.
   */
  final ResourceProvider provider;

  /**
   * The absolute workspace root path (the directory containing the `.jiri_root`
   * directory).
   */
  final String root;

  /**
   * The paths to the .packages files.
   */
  final List<String> _packagesFilePaths;

  /**
   * The map of package locations indexed by package name.
   *
   * This is a cached field.
   */
  Map<String, List<Folder>> _packageMap;

  /**
   * The package location strategy.
   *
   * This is a cached field.
   */
  Packages _packages;

  GnWorkspace._(this.provider, this.root, this._packagesFilePaths);

  @override
  Map<String, List<Folder>> get packageMap =>
      _packageMap ??= _convertPackagesToMap(packages);

  Packages get packages => _packages ??= _createPackages();

  @override
  UriResolver get packageUriResolver =>
      new PackageMapUriResolver(provider, packageMap);

  @override
  SourceFactory createSourceFactory(DartSdk sdk, SummaryDataStore summaryData) {
    if (summaryData != null) {
      throw new UnsupportedError(
          'Summary files are not supported in a GN workspace.');
    }
    List<UriResolver> resolvers = <UriResolver>[];
    if (sdk != null) {
      resolvers.add(new DartUriResolver(sdk));
    }
    resolvers.add(packageUriResolver);
    resolvers.add(new ResourceUriResolver(provider));
    return new SourceFactory(resolvers, packages, provider);
  }

  /**
   * Return the file with the given [absolutePath].
   *
   * Return `null` if the given [absolutePath] is not in the workspace [root].
   */
  File findFile(String absolutePath) {
    try {
      File writableFile = provider.getFile(absolutePath);
      if (writableFile.exists) {
        return writableFile;
      }
    } catch (_) {}
    return null;
  }

  @override
  WorkspacePackage findPackageFor(String path) {
    Folder folder = provider.getFolder(provider.pathContext.dirname(path));

    while (true) {
      Folder parent = folder.parent;
      if (parent == null) {
        return null;
      }
      if (parent.path.length < root.length) {
        // We've walked up outside of [root], so [path] is definitely not
        // defined in any package in this workspace.
        return null;
      }

      if (folder.getChildAssumingFile(_buildFileName).exists) {
        return GnWorkspacePackage(folder.path, this);
      }

      // Go up a folder.
      folder = parent;
    }
  }

  /**
   * Creates an alternate representation for available packages.
   */
  Map<String, List<Folder>> _convertPackagesToMap(Packages packages) {
    Map<String, List<Folder>> folderMap = new HashMap<String, List<Folder>>();
    if (packages != null && packages != Packages.noPackages) {
      var pathContext = provider.pathContext;
      packages.asMap().forEach((String packageName, Uri uri) {
        String filePath = fileUriToNormalizedPath(pathContext, uri);
        folderMap[packageName] = [provider.getFolder(filePath)];
      });
    }
    return folderMap;
  }

  /**
   * Loads the packages from the .packages file.
   */
  Packages _createPackages() {
    Map<String, Uri> map = _packagesFilePaths.map((String filePath) {
      File configFile = provider.getFile(filePath);
      List<int> bytes = configFile.readAsBytesSync();
      return parse(bytes, configFile.toUri());
    }).reduce((mapOne, mapTwo) {
      mapOne.addAll(mapTwo);
      return mapOne;
    });
    _resolveSymbolicLinks(map);
    return new MapPackages(map);
  }

  /**
   * Resolve any symbolic links encoded in the path to the given [folder].
   */
  String _resolveSymbolicLink(Folder folder) {
    try {
      return folder.resolveSymbolicLinksSync().path;
    } on FileSystemException {
      return folder.path;
    }
  }

  /**
   * Resolve any symbolic links encoded in the URI's in the given [map] by
   * replacing the values in the map.
   */
  void _resolveSymbolicLinks(Map<String, Uri> map) {
    path.Context pathContext = provider.pathContext;
    for (String packageName in map.keys) {
      String filePath = fileUriToNormalizedPath(pathContext, map[packageName]);
      Folder folder = provider.getFolder(filePath);
      String folderPath = _resolveSymbolicLink(folder);
      // Add a '.' so that the URI is suitable for resolving relative URI's
      // against it.
      String uriPath = pathContext.join(folderPath, '.');
      map[packageName] = pathContext.toUri(uriPath);
    }
  }

  /**
   * Find the GN workspace that contains the given [filePath].
   *
   * Return `null` if a workspace could not be found. For a workspace to be
   * found, both a `.jiri_root` file must be found, and at least one "packages"
   * file must be found in [filePath]'s output directory.
   */
  static GnWorkspace find(ResourceProvider provider, String filePath) {
    Folder folder = provider.getFolder(filePath);
    while (true) {
      Folder parent = folder.parent;
      if (parent == null) {
        return null;
      }

      if (folder.getChildAssumingFolder(_jiriRootName).exists) {
        // Found the .jiri_root file, must be a non-git workspace.
        String root = folder.path;
        List<String> packagesFiles =
            _findPackagesFile(provider, root, filePath);
        if (packagesFiles.isEmpty) {
          return null;
        }
        return new GnWorkspace._(provider, root, packagesFiles);
      }

      // Go up a folder.
      folder = parent;
    }
  }

  /**
   * For a source at `$root/foo/bar`, the packages files are generated in
   * `$root/out/<debug|release>-XYZ/dartlang/gen/foo/bar`.
   *
   * Note that in some cases multiple .packages files can be found at that
   * location, for example if the package contains both a library and a binary
   * target. For a complete view of the package, all of these files need to be
   * taken into account.
   */
  static List<String> _findPackagesFile(
    ResourceProvider provider,
    String root,
    String filePath,
  ) {
    path.Context pathContext = provider.pathContext;
    String sourceDirectory = pathContext.relative(filePath, from: root);
    Folder outDirectory = _getOutDirectory(root, provider);
    if (outDirectory == null) {
      return const <String>[];
    }
    Folder genDir = outDirectory.getChildAssumingFolder(
        pathContext.join('dartlang', 'gen', sourceDirectory));
    if (!genDir.exists) {
      return const <String>[];
    }
    return genDir
        .getChildren()
        .where((resource) => resource is File)
        .map((resource) => resource as File)
        .where((File file) => pathContext.extension(file.path) == '.packages')
        .map((File file) => file.path)
        .toList();
  }

  /**
   * Returns the output directory of the build, or `null` if it could not be
   * found.
   *
   * First attempts to read a config file at the root of the source tree. If
   * that file cannot be found, looks for standard output directory locations.
   */
  static Folder _getOutDirectory(String root, ResourceProvider provider) {
    path.Context pathContext = provider.pathContext;
    File config = provider.getFile(pathContext.join(root, '.config'));
    if (config.exists) {
      String content = config.readAsStringSync();
      Match match =
          new RegExp(r'^FUCHSIA_BUILD_DIR=["\x27](.+)["\x27]$', multiLine: true)
              .firstMatch(content);
      if (match != null) {
        String buildDirPath = match.group(1);
        if (pathContext.isRelative(buildDirPath)) {
          buildDirPath = pathContext.join(root, buildDirPath);
        }
        return provider.getFolder(buildDirPath);
      }
    }
    Folder outDirectory = provider.getFolder(pathContext.join(root, 'out'));
    if (!outDirectory.exists) {
      return null;
    }
    return outDirectory
        .getChildren()
        .where((resource) => resource is Folder)
        .map((resource) => resource as Folder)
        .firstWhere((Folder folder) {
      String baseName = pathContext.basename(folder.path);
      // Taking a best guess to identify a build dir. This is clearly a fallback
      // to the config-based method.
      return baseName.startsWith('debug') || baseName.startsWith('release');
    }, orElse: () => null);
  }
}

/**
 * Information about a package defined in a GnWorkspace.
 *
 * Separate from [Packages] or package maps, this class is designed to simply
 * understand whether arbitrary file paths represent libraries declared within
 * a given package in a GnWorkspace.
 */
class GnWorkspacePackage extends WorkspacePackage {
  final String root;

  final GnWorkspace workspace;

  GnWorkspacePackage(this.root, this.workspace);

  @override
  bool contains(String path) {
    if (workspace.findFile(path) == null) {
      return false;
    }
    if (!workspace.provider.pathContext.isWithin(root, path)) {
      return false;
    }

    // Just because [path] is within [root] does not mean it is in this
    // package; it could be in a "subpackage." Must go through the work of
    // learning exactly which package [path] is contained in.
    return workspace.findPackageFor(path).root == root;
  }
}
