// 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.');
    }
    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.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.
    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;

  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;
}
