// 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 a reference to a path package named [name] at [path].
  // PackageRef<PathDescription> refFor(String name, String path) {
  //   if (p.isRelative(path)) {
  //     PackageRef(name, {'path':p.absolute(path), 'relative': p.isRelative(path)});
  //   }
  //   return PackageRef(name, {'path': path, 'relative': p.isRelative(path)});
  // }
//{name: myapp, dev_dependencies: {foo: 1.2.2}, dependency_overrides: {foo: {path: ../foo}}, environment: {sdk: >=0.1.2 <1.0.0}}
//{name: myapp, dev_dependencies: {foo: ^1.2.2}, dependency_overrides: {foo: {path: ../foo}}, environment: {sdk: >=0.1.2 <1.0.0}}
  /// 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 FormatException('The description must be a path string.');
    }
    var dir = description;
    // Resolve the path relative to the containing file path, and remember
    // whether the original path was relative or absolute.
    var 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.joinAll([
        containingDescription.path,
        ...p.posix.split(dir),
      ]);
      if (!p.isWithin('.', 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: p.normalize(
            p.join(
              containingDescription.path,
              dir,
            ),
          ),
        ),
      );
    } 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 FormatException('The description must be a map.');
    }
    var path = description['path'];
    if (path is! String) {
      throw FormatException("The 'path' field of the description must "
          'be a string.');
    }
    final relative = description['relative'];
    if (relative is! bool) {
      throw 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.
    var pubspec = _loadPubspec(ref, cache);
    var 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');
    }
    var 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;

  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 &&
        canonicalize(path) == canonicalize(other.path);
  }

  @override
  int get hashCode => canonicalize(path).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;
}
