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

  /// Optional field to specify executables
  @JsonKey(fromJson: _executablesMap)
  final Map<String, String?> executables;

  /// If this package is a Pub Workspace, this field lists the sub-packages.
  final List<String>? workspace;

  /// Specifies how to resolve dependencies with the surrounding Pub Workspace.
  final String? resolution;

  /// 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,
    this.workspace,
    this.resolution,
    Map<String, Dependency>? dependencies,
    Map<String, Dependency>? devDependencies,
    Map<String, Dependency>? dependencyOverrides,
    this.flutter,
    Map<String, String?>? executables,
  }) : authors // ignore: deprecated_member_use_from_same_package
       = _normalizeAuthors(
         author,
         authors,
       ),
       environment = environment ?? const {},
       dependencies = dependencies ?? const {},
       devDependencies = devDependencies ?? const {},
       executables = executables ?? 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);
    }) ??
    {};

Map<String, String?> _executablesMap(Map? source) =>
    source?.map((k, value) {
      final key = k as String;
      if (value == null) {
        return MapEntry(key, null);
      } else if (value is String) {
        return MapEntry(key, value);
      } else {
        throw CheckedFromJsonException(
          source,
          key,
          'String',
          '`$value` is not a String.',
        );
      }
    }) ??
    {};
