// Copyright (c) 2023, 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:io';

import 'package:glob/glob.dart';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:yaml/yaml.dart' as yaml;

import 'changelog.dart';
import 'github.dart';

class Repository {
  final Directory baseDirectory;

  Repository([Directory? base]) : baseDirectory = base ?? Directory.current;

  /// Returns true if this repository hosts only a single package, and that
  /// package lives at the top level of the repo.
  bool get isSinglePackageRepo {
    var packages = locatePackages();
    if (packages.length != 1) {
      return false;
    }

    var dir = packages.single.directory;
    return dir.absolute.path == baseDirectory.absolute.path;
  }

  /// Returns all the potentially publishable packages for the current
  /// repository.
  ///
  /// This could be one package - if this is a single package repository - or
  /// multiple packages, if this is a monorepo.
  ///
  /// Packages will be returned if their pubspec doesn't contain a
  /// `publish_to: none` key.
  ///
  /// Once we find a package, we don't look for packages in sub-directories.
  List<Package> locatePackages([List<Glob> ignore = const []]) {
    final packages = <Package>[];
    _recurseAndGather(baseDirectory, packages);
    packages.removeWhere((package) => ignore.any((glob) => glob.matches(
        path.relative(package.directory.path, from: baseDirectory.path))));
    packages.sort((a, b) => a.name.compareTo(b.name));
    return packages;
  }

  void _recurseAndGather(Directory directory, List<Package> packages) {
    var pubspecFile = File(path.join(directory.path, 'pubspec.yaml'));

    if (pubspecFile.existsSync()) {
      var pubspec = yaml.loadYaml(pubspecFile.readAsStringSync()) as Map;
      var publishTo = pubspec['publish_to'] as String?;
      if (publishTo != 'none' && !pubspec.containsKey('workspace')) {
        packages.add(Package(directory, this));
        // There is an assumption here that published, non-workspace packages do
        // not contain nested published packages.
        return;
      }
    }
    if (directory.existsSync()) {
      for (var child in directory.listSync().whereType<Directory>()) {
        var name = path.basename(child.path);
        if (!name.startsWith('.')) {
          _recurseAndGather(child, packages);
        }
      }
    }
  }

  String calculateRepoTag(Package package) {
    if (isSinglePackageRepo) {
      return 'v${package.pubspec.version}';
    } else {
      return '${package.name}-v${package.pubspec.version}';
    }
  }

  Uri calculateReleaseUri(Package package, GithubApi github) {
    final tag = calculateRepoTag(package);
    final title = 'package:${package.name} v${package.pubspec.version}';
    final body = package.changelog.describeLatestChanges;
    return Uri.https('github.com', '/${github.repoSlug}/releases/new',
        {'tag': tag, 'title': title, 'body': body});
  }
}

class Package {
  final Directory directory;
  final Repository repository;

  late final Pubspec pubspec;
  late final Changelog changelog;

  Package(this.directory, this.repository) {
    pubspec = Pubspec.parse(_getPackageFile('pubspec.yaml').readAsStringSync());
    changelog = Changelog(_getPackageFile('CHANGELOG.md'));
  }

  File _getPackageFile(String fileName) =>
      File(path.join(directory.path, fileName));

  String get name => pubspec.name;

  Version? get version => pubspec.version;

  @override
  String toString() =>
      'package:${pubspec.name} ${pubspec.version} (dir=${directory.path})';
}
