// Copyright (c) 2013, 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 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';

import '../exceptions.dart';
import '../io.dart';
import '../language_version.dart';
import '../package_name.dart';
import '../pubspec.dart';
import '../source.dart';
import '../system_cache.dart';
import 'git.dart';
import 'hosted.dart';
import 'root.dart';

/// A package [Source] that gets packages from a given local file path.
class PathSource extends Source {
  static PathSource instance = PathSource._();
  PathSource._();

  @override
  final name = 'path';

  /// Returns an ID for a path package with the given [name] and [version] at
  /// [path].
  ///
  /// If [path] is relative it is resolved relative to [relativeTo]
  PackageId idFor(
    String name,
    Version version,
    String path,
    String relativeTo,
  ) {
    return PackageId(
      name,
      version,
      ResolvedPathDescription(
        PathDescription(p.join(relativeTo, path), p.isRelative(path)),
      ),
    );
  }

  /// Parses a path dependency.
  ///
  /// This takes in a path string and returns a map. The "path" key will be the
  /// original path but resolved relative to the containing path. The
  /// "relative" key will be `true` if the original path was relative.
  @override
  PackageRef parseRef(
    String name,
    Object? description, {
    required Description containingDescription,
    LanguageVersion? languageVersion,
  }) {
    if (description is! String) {
      throw const FormatException('The description must be a path string.');
    }
    final dir = description;
    // Resolve the path relative to the containing file path, and remember
    // whether the original path was relative or absolute.
    final isRelative = p.isRelative(dir);

    if (containingDescription is PathDescription) {
      return PackageRef(
        name,
        PathDescription(
          isRelative
              ? p.join(p.absolute(containingDescription.path), dir)
              : dir,
          isRelative,
        ),
      );
    } else if (containingDescription is RootDescription) {
      return PackageRef(
        name,
        PathDescription(
          p.normalize(
            p.join(p.absolute(containingDescription.path), description),
          ),
          isRelative,
        ),
      );
    } else if (containingDescription is GitDescription) {
      if (!isRelative) {
        throw FormatException(
          '"$description" is an absolute path, '
          'it can\'t be referenced from a git pubspec.',
        );
      }
      final resolvedPath = p.url.normalize(
        p.url.joinAll([containingDescription.path, ...p.posix.split(dir)]),
      );
      if (!(p.isWithin('.', resolvedPath) || p.equals('.', resolvedPath))) {
        throw FormatException(
          'the path "$description" '
          'cannot refer outside the git repository $resolvedPath.',
        );
      }
      return PackageRef(
        name,
        GitDescription.raw(
          url: containingDescription.url,
          relative: containingDescription.relative,
          ref: containingDescription.ref,
          path: resolvedPath,
        ),
      );
    } else if (containingDescription is HostedDescription) {
      if (isRelative) {
        throw FormatException(
          '"$description" is a relative path, but this '
          'isn\'t a local pubspec.',
        );
      }
      return PackageRef(name, PathDescription(dir, false));
    } else {
      throw FormatException(
        '"$description" is a path, but this '
        'isn\'t a local pubspec.',
      );
    }
  }

  @override
  PackageId parseId(
    String name,
    Version version,
    Object? description, {
    String? containingDir,
  }) {
    if (description is! Map) {
      throw const FormatException('The description must be a map.');
    }
    var path = description['path'];
    if (path is! String) {
      throw const FormatException(
        "The 'path' field of the description must "
        'be a string.',
      );
    }
    final relative = description['relative'];
    if (relative is! bool) {
      throw const FormatException(
        "The 'relative' field of the description "
        'must be a boolean.',
      );
    }

    // Resolve the path relative to the containing file path.
    if (relative) {
      // Relative paths coming from lockfiles that are not on the local file
      // system aren't allowed.
      if (containingDir == null) {
        throw FormatException(
          '"$description" is a relative path, but this '
          'isn\'t a local pubspec.',
        );
      }

      path = p.normalize(p.absolute(p.join(containingDir, path)));
    }

    return PackageId(
      name,
      version,
      ResolvedPathDescription(PathDescription(path, relative)),
    );
  }

  /// On both Windows and linux we prefer `/` in the pubspec.lock for relative
  /// paths.
  static String relativePathWithPosixSeparators(String path) {
    assert(p.isRelative(path));
    return p.posix.joinAll(p.split(path));
  }

  @override
  Future<List<PackageId>> doGetVersions(
    PackageRef ref,
    Duration? maxAge,
    SystemCache cache,
  ) async {
    final description = ref.description;
    if (description is! PathDescription) {
      throw ArgumentError('Wrong source');
    }
    // There's only one package ID for a given path. We just need to find the
    // version.
    final pubspec = _loadPubspec(ref, cache);
    final id = PackageId(
      ref.name,
      pubspec.version,
      ResolvedPathDescription(description),
    );
    // Store the pubspec in memory if we need to refer to it again.
    cache.cachedPubspecs[id] = pubspec;
    return [id];
  }

  @override
  Future<Pubspec> doDescribe(PackageId id, SystemCache cache) async =>
      _loadPubspec(id.toRef(), cache);

  Pubspec _loadPubspec(PackageRef ref, SystemCache cache) {
    final description = ref.description;
    if (description is! PathDescription) {
      throw ArgumentError('Wrong source');
    }
    final dir = _validatePath(ref.name, description);
    return Pubspec.load(
      dir,
      cache.sources,
      containingDescription: description,
      expectedName: ref.name,
    );
  }

  @override
  String doGetDirectory(
    PackageId id,
    SystemCache cache, {
    String? relativeFrom,
  }) {
    final description = id.description.description;
    if (description is! PathDescription) {
      throw ArgumentError('Wrong source');
    }
    return description.relative
        ? p.relative(description.path, from: relativeFrom)
        : description.path;
  }

  /// Ensures that [description] is a valid path description and returns a
  /// normalized path to the package.
  ///
  /// It must be a map, with a "path" key containing a path that points to an
  /// existing directory. Throws an [PackageNotFoundException] if the path is
  /// invalid or a pubspec.yaml file doesn't exist at the location.
  String _validatePath(String name, PathDescription description) {
    final dir = description.path;

    if (dirExists(dir)) {
      final pubspecPath = p.join(dir, 'pubspec.yaml');
      if (!fileExists(pubspecPath)) {
        throw PackageNotFoundException(
          'No pubspec.yaml found for package $name in $dir.',
          innerError: FileException('$pubspecPath doesn\'t exist', pubspecPath),
        );
      }
      return dir;
    }
    if (fileExists(dir)) {
      throw PackageNotFoundException(
        'Path dependency for package $name must refer to a directory, '
        'not a file. Was "$dir".',
        innerError: FileException('$dir is not a directory.', dir),
      );
    }
    throw PackageNotFoundException(
      'could not find package $name at "${description.format()}"',
      innerError: FileException('$dir does not exist.', dir),
    );
  }
}

class PathDescription extends Description {
  final String path;
  final bool relative;

  // Canonicalization is rather slow - cache the result;
  late final String _canonicalizedPath = canonicalize(path);

  PathDescription(this.path, this.relative) : assert(!p.isRelative(path));
  @override
  String format() {
    return relative ? p.relative(path) : path;
  }

  @override
  Object? serializeForPubspec({
    required String? containingDir,
    required LanguageVersion languageVersion,
  }) {
    return relative
        ? PathSource.relativePathWithPosixSeparators(
          p.relative(path, from: containingDir),
        )
        : path;
  }

  @override
  Source get source => PathSource.instance;

  @override
  bool operator ==(Object other) {
    return other is PathDescription &&
        _canonicalizedPath == other._canonicalizedPath;
  }

  @override
  int get hashCode => _canonicalizedPath.hashCode;
}

class ResolvedPathDescription extends ResolvedDescription {
  @override
  PathDescription get description => super.description as PathDescription;

  ResolvedPathDescription(PathDescription super.description);

  @override
  Object? serializeForLockfile({required String? containingDir}) {
    if (description.relative) {
      return {
        'path': PathSource.relativePathWithPosixSeparators(
          p.relative(description.path, from: containingDir),
        ),
        'relative': true,
      };
    }
    return {'path': description.path, 'relative': p.relative('false')};
  }

  @override
  bool operator ==(Object other) =>
      other is ResolvedPathDescription && other.description == description;

  @override
  int get hashCode => description.hashCode;
}
