// Copyright (c) 2018, 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 'package:checked_yaml/checked_yaml.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:pub_semver/pub_semver.dart';

import 'dependency.dart';
import 'screenshot.dart';

part 'pubspec.g.dart';

@JsonSerializable()
class Pubspec {
  // TODO: executables

  final String name;

  @JsonKey(fromJson: _versionFromString)
  final Version? version;

  final String? description;

  /// This should be a URL pointing to the website for the package.
  final String? homepage;

  /// Specifies where to publish this package.
  ///
  /// Accepted values: `null`, `'none'` or an `http` or `https` URL.
  ///
  /// [More information](https://dart.dev/tools/pub/pubspec#publish_to).
  final String? publishTo;

  /// Optional field to specify the source code repository of the package.
  /// Useful when a package has both a home page and a repository.
  final Uri? repository;

  /// Optional field to a web page where developers can report new issues or
  /// view existing ones.
  final Uri? issueTracker;

  /// Optional field to list the URLs where the package authors accept
  /// support or funding.
  final List<Uri>? funding;

  /// Optional field to list the topics that this packages belongs to.
  final List<String>? topics;

  /// Optional field to list advisories to be ignored by the client.
  final List<String>? ignoredAdvisories;

  /// Optional field for specifying included screenshot files.
  @JsonKey(fromJson: parseScreenshots)
  final List<Screenshot>? screenshots;

  /// If there is exactly 1 value in [authors], returns it.
  ///
  /// If there are 0 or more than 1, returns `null`.
  @Deprecated(
    'See https://dart.dev/tools/pub/pubspec#authorauthors',
  )
  String? get author {
    if (authors.length == 1) {
      return authors.single;
    }
    return null;
  }

  @Deprecated(
    'See https://dart.dev/tools/pub/pubspec#authorauthors',
  )
  final List<String> authors;
  final String? documentation;

  @JsonKey(fromJson: _environmentMap)
  final Map<String, VersionConstraint?> environment;

  @JsonKey(fromJson: parseDeps)
  final Map<String, Dependency> dependencies;

  @JsonKey(fromJson: parseDeps)
  final Map<String, Dependency> devDependencies;

  @JsonKey(fromJson: parseDeps)
  final Map<String, Dependency> dependencyOverrides;

  /// Optional configuration specific to [Flutter](https://flutter.io/)
  /// packages.
  ///
  /// May include
  /// [assets](https://flutter.io/docs/development/ui/assets-and-images)
  /// and other settings.
  final Map<String, dynamic>? flutter;

  /// If [author] and [authors] are both provided, their values are combined
  /// with duplicates eliminated.
  Pubspec(
    this.name, {
    this.version,
    this.publishTo,
    @Deprecated(
      'See https://dart.dev/tools/pub/pubspec#authorauthors',
    )
    String? author,
    @Deprecated(
      'See https://dart.dev/tools/pub/pubspec#authorauthors',
    )
    List<String>? authors,
    Map<String, VersionConstraint?>? environment,
    this.homepage,
    this.repository,
    this.issueTracker,
    this.funding,
    this.topics,
    this.ignoredAdvisories,
    this.screenshots,
    this.documentation,
    this.description,
    Map<String, Dependency>? dependencies,
    Map<String, Dependency>? devDependencies,
    Map<String, Dependency>? dependencyOverrides,
    this.flutter,
  })  :
        // ignore: deprecated_member_use_from_same_package
        authors = _normalizeAuthors(author, authors),
        environment = environment ?? const {},
        dependencies = dependencies ?? const {},
        devDependencies = devDependencies ?? const {},
        dependencyOverrides = dependencyOverrides ?? const {} {
    if (name.isEmpty) {
      throw ArgumentError.value(name, 'name', '"name" cannot be empty.');
    }

    if (publishTo != null && publishTo != 'none') {
      try {
        final targetUri = Uri.parse(publishTo!);
        if (!(targetUri.isScheme('http') || targetUri.isScheme('https'))) {
          throw const FormatException('Must be an http or https URL.');
        }
      } on FormatException catch (e) {
        throw ArgumentError.value(publishTo, 'publishTo', e.message);
      }
    }
  }

  factory Pubspec.fromJson(Map json, {bool lenient = false}) {
    if (lenient) {
      while (json.isNotEmpty) {
        // Attempting to remove top-level properties that cause parsing errors.
        try {
          return _$PubspecFromJson(json);
        } on CheckedFromJsonException catch (e) {
          if (e.map == json && json.containsKey(e.key)) {
            json = Map.from(json)..remove(e.key);
            continue;
          }
          rethrow;
        }
      }
    }

    return _$PubspecFromJson(json);
  }

  /// Parses source [yaml] into [Pubspec].
  ///
  /// When [lenient] is set, top-level property-parsing or type cast errors are
  /// ignored and `null` values are returned.
  factory Pubspec.parse(String yaml, {Uri? sourceUrl, bool lenient = false}) =>
      checkedYamlDecode(
        yaml,
        (map) => Pubspec.fromJson(map!, lenient: lenient),
        sourceUrl: sourceUrl,
      );

  static List<String> _normalizeAuthors(String? author, List<String>? authors) {
    final value = <String>{
      if (author != null) author,
      ...?authors,
    };
    return value.toList();
  }
}

Version? _versionFromString(String? input) =>
    input == null ? null : Version.parse(input);

Map<String, VersionConstraint?> _environmentMap(Map? source) =>
    source?.map((k, value) {
      final key = k as String;
      if (key == 'dart') {
        // github.com/dart-lang/pub/blob/d84173eeb03c3/lib/src/pubspec.dart#L342
        // 'dart' is not allowed as a key!
        throw CheckedFromJsonException(
          source,
          'dart',
          'VersionConstraint',
          'Use "sdk" to for Dart SDK constraints.',
          badKey: true,
        );
      }

      VersionConstraint? constraint;
      if (value == null) {
        constraint = null;
      } else if (value is String) {
        try {
          constraint = VersionConstraint.parse(value);
        } on FormatException catch (e) {
          throw CheckedFromJsonException(source, key, 'Pubspec', e.message);
        }

        return MapEntry(key, constraint);
      } else {
        throw CheckedFromJsonException(
          source,
          key,
          'VersionConstraint',
          '`$value` is not a String.',
        );
      }

      return MapEntry(key, constraint);
    }) ??
    {};
