// 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 {
  static final SdkSource instance = SdkSource._();

  SdkSource._();

  @override
  final name = 'sdk';

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

    return PackageRef(name, SdkDescription(description));
  }

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

    return PackageId(
      name,
      version,
      ResolvedSdkDescription(SdkDescription(description)),
    );
  }

  @override
  Future<List<PackageId>> doGetVersions(
    PackageRef ref,
    Duration? maxAge,
    SystemCache cache,
  ) async {
    final description = ref.description;
    if (description is! SdkDescription) {
      throw ArgumentError('Wrong source');
    }
    final pubspec = _loadPubspec(ref, cache);
    final id = PackageId(
      ref.name,
      pubspec.version,
      ResolvedSdkDescription(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);

  /// Loads the pubspec for the SDK package named [ref].
  ///
  /// Throws a [PackageNotFoundException] if [ref]'s SDK is unavailable or
  /// doesn't contain the package.
  Pubspec _loadPubspec(PackageRef ref, SystemCache cache) {
    final pubspec = Pubspec.load(
      _verifiedPackagePath(ref),
      cache.sources,
      expectedName: ref.name,
      containingDescription: ref.description,
    );

    /// Validate that there are no non-sdk dependencies if the SDK does not
    /// allow them.
    if (ref.description case final SdkDescription description) {
      if (sdks[description.sdk] case Sdk(
        allowsNonSdkDepsInSdkPackages: false,
      )) {
        for (var dep in pubspec.dependencies.entries) {
          if (dep.value.source is! SdkSource) {
            throw UnsupportedError(
              'Only SDK packages are allowed as regular dependencies for '
              'packages vendored by the ${sdk.identifier} SDK, but the '
              '`${ref.name}` package has a ${dep.value.source.name} dependency '
              'on `${dep.key}`.',
            );
          }
        }
      }
    }
    return pubspec;
  }

  /// Returns the path for the given [ref].
  ///
  /// Throws a [PackageNotFoundException] if [ref]'s SDK is unavailable or
  /// doesn't contain the package.
  String _verifiedPackagePath(PackageRef ref) {
    final description = ref.description;
    if (description is! SdkDescription) {
      throw ArgumentError('Wrong source');
    }
    final sdkName = description.sdk;
    final sdk = sdks[sdkName];
    if (sdk == null) {
      throw PackageNotFoundException('unknown SDK "$sdkName"');
    } else if (!sdk.isAvailable) {
      throw PackageNotFoundException(
        'the ${sdk.name} SDK is not available',
        hint: sdk.installMessage,
      );
    }

    final path = sdk.packagePath(ref.name);
    if (path != null) return path;

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

  @override
  String doGetDirectory(
    PackageId id,
    SystemCache cache, {
    String? relativeFrom,
  }) {
    try {
      return _verifiedPackagePath(id.toRef());
    } 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)}.');
    }
  }
}

class SdkDescription extends Description {
  /// The sdk the described package comes from.
  final String sdk;

  SdkDescription(this.sdk);
  @override
  String format() => sdk;

  @override
  Object? serializeForPubspec({
    required String? containingDir,
    required LanguageVersion languageVersion,
  }) {
    return sdk;
  }

  @override
  Source get source => SdkSource.instance;

  @override
  int get hashCode => sdk.hashCode;

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

class ResolvedSdkDescription extends ResolvedDescription {
  @override
  SdkDescription get description => super.description as SdkDescription;

  ResolvedSdkDescription(SdkDescription super.description);

  @override
  Object? serializeForLockfile({required String? containingDir}) {
    return description.sdk;
  }

  @override
  int get hashCode => description.hashCode;

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