// Copyright (c) 2016, 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:pub_semver/pub_semver.dart';

import '../exceptions.dart';
import '../language_version.dart';
import '../package_name.dart';
import '../pubspec.dart';
import '../sdk.dart';
import '../source.dart';
import '../system_cache.dart';
import '../utils.dart';

/// A package [Source] that gets packages from a hard-coded SDK.
class SdkSource extends Source {
  @override
  final name = 'sdk';

  @override
  BoundSource bind(SystemCache systemCache) =>
      BoundSdkSource(this, systemCache);

  /// Returns a reference to an SDK package named [name] from [sdk].
  PackageRef refFor(String name, String sdk) => PackageRef(name, this, sdk);

  /// Returns an ID for an SDK package with the given [name] and [version] from
  /// [sdk].
  PackageId idFor(String name, Version version, String sdk) =>
      PackageId(name, this, version, sdk);

  /// Parses an SDK dependency.
  @override
  PackageRef parseRef(String name, description,
      {String? containingPath, LanguageVersion? languageVersion}) {
    if (description is! String) {
      throw FormatException('The description must be an SDK name.');
    }

    return PackageRef(name, this, description);
  }

  @override
  PackageId parseId(String name, Version version, description,
      {String? containingPath}) {
    if (description is! String) {
      throw FormatException('The description must be an SDK name.');
    }

    return PackageId(name, this, version, description);
  }

  @override
  bool descriptionsEqual(description1, description2) =>
      description1 == description2;

  @override
  int hashDescription(description) => description.hashCode;
}

/// The [BoundSource] for [SdkSource].
class BoundSdkSource extends BoundSource {
  @override
  final SdkSource source;

  @override
  final SystemCache systemCache;

  BoundSdkSource(this.source, this.systemCache);

  @override
  Future<List<PackageId>> doGetVersions(
      PackageRef ref, Duration? maxAge) async {
    var pubspec = _loadPubspec(ref);
    var id = PackageId(ref.name, source, pubspec.version, ref.description);
    memoizePubspec(id, pubspec);
    return [id];
  }

  @override
  Future<Pubspec> doDescribe(PackageId id) async => _loadPubspec(id);

  /// Loads the pubspec for the Flutter package named [name].
  ///
  /// Throws a [PackageNotFoundException] if [package]'s SDK is unavailable or
  /// doesn't contain the package.
  Pubspec _loadPubspec(PackageName package) =>
      Pubspec.load(_verifiedPackagePath(package), systemCache.sources,
          expectedName: package.name);

  /// Returns the path for the given [package].
  ///
  /// Throws a [PackageNotFoundException] if [package]'s SDK is unavailable or
  /// doesn't contain the package.
  String _verifiedPackagePath(PackageName package) {
    var identifier = package.description as String?;
    var sdk = sdks[identifier!];
    if (sdk == null) {
      throw PackageNotFoundException('unknown SDK "$identifier"');
    } else if (!sdk.isAvailable) {
      throw PackageNotFoundException(
        'the ${sdk.name} SDK is not available',
        hint: sdk.installMessage,
      );
    }

    var path = sdk.packagePath(package.name);
    if (path != null) return path;

    throw PackageNotFoundException(
        'could not find package ${package.name} in the ${sdk.name} SDK');
  }

  @override
  String getDirectory(PackageId id, {String? relativeFrom}) {
    try {
      return _verifiedPackagePath(id);
    } on PackageNotFoundException catch (error) {
      // [PackageNotFoundException]s are uncapitalized and unpunctuated because
      // they're used within other sentences by the version solver, but
      // [ApplicationException]s should be full sentences.
      throw ApplicationException(capitalize(error.message) + '.');
    }
  }
}
