// Copyright (c) 2013, 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.

/// Pub-specific test descriptors.
library;

import 'dart:convert';

import 'package:path/path.dart' as p;
import 'package:pub/src/language_version.dart';
import 'package:pub/src/oauth2.dart';
import 'package:pub/src/package_config.dart';
import 'package:pub/src/sdk/sdk_package_config.dart';
import 'package:test_descriptor/test_descriptor.dart';

import 'descriptor/git.dart';
import 'descriptor/package_config.dart';
import 'descriptor/tar.dart';
import 'descriptor/yaml.dart';
import 'test_pub.dart';

export 'package:test_descriptor/test_descriptor.dart';

export 'descriptor/git.dart';
export 'descriptor/package_config.dart';
export 'descriptor/tar.dart';

/// Creates a new [GitRepoDescriptor] with [name] and [contents].
GitRepoDescriptor git(String name, [List<Descriptor>? contents]) =>
    GitRepoDescriptor(name, contents ?? <Descriptor>[]);

/// Creates a new [TarFileDescriptor] with [name] and [contents].
TarFileDescriptor tar(String name, [List<Descriptor>? contents]) =>
    TarFileDescriptor(name, contents ?? <Descriptor>[]);

FileDescriptor validPubspec({Map<String, Object?>? extras}) =>
    libPubspec('test_pkg', '1.0.0', sdk: '>=3.1.2 <=3.2.0', extras: extras);

/// Describes a package that passes all validation.
DirectoryDescriptor validPackage({
  String version = '1.0.0',
  Map<String, Object?>? pubspecExtras,
}) =>
    dir(appPath, [
      validPubspec(extras: {'version': version, ...?pubspecExtras}),
      file('LICENSE', 'Eh, do what you want.'),
      file('README.md', "This package isn't real."),
      file('CHANGELOG.md', '# $version\nFirst version\n'),
      dir('lib', [file('test_pkg.dart', 'int i = 1;')]),
    ]);

/// Returns a descriptor of a snapshot that can't be run by the current VM.
///
/// This snapshot was generated using version 2.0.0-dev.58.0 of the VM.
FileDescriptor outOfDateSnapshot(String name) => file(
      name,
      base64.decode(
        'kKvN7wAAAAYBAAEAAQAAAAAAAAABBgMBBh8AAQEAAAABA'
        'wofAAAAAAAAAFwBShABHhAGAQABJwIAAAAAEwAAAAAAAA'
        'AVAAAAOQAAAAEAAAACAAAAJWZpbGU6Ly8vVXNlcnMvcm5'
        '5c3Ryb20vdGVtcC90ZW1wLmRhcnQgdm9pZCBtYWluKCkg'
        'PT4gcHJpbnQoJ2hlbGxvIScpOwoDACABAAAAUQAAAFQGA'
        'AMBBAIBAAUEBAUGAAAAAAcABAovN0BFbWFpbmhlbGxvIW'
        'ZpbGU6Ly8vVXNlcnMvcm55c3Ryb20vdGVtcC90ZW1wLmR'
        'hcnRAbWV0aG9kc2RhcnQ6Y29yZXByaW50AAAAAE0AAACn'
        'AAAAtAAAALQAAAC4AAABBQAAAAMAAAAJAAAATQAAAAEAA'
        'AEy',
      ),
    );

/// Describes a file named `pubspec.yaml` with the given YAML-serialized
/// [contents], which should be a serializable object.
///
/// [contents] may contain [Future]s that resolve to serializable objects,
/// which may in turn contain [Future]s recursively.
FileDescriptor pubspec(Map<String, Object?> contents) => YamlDescriptor(
      'pubspec.yaml',
      yaml({
        ...contents,
        // TODO: Copy-pasting this into all call-sites, or use d.libPubspec
        'environment': {
          'sdk': defaultSdkConstraint,
          ...(contents['environment'] ?? {}) as Map,
        },
      }),
    );

Descriptor rawPubspec(Map<String, Object> contents) =>
    YamlDescriptor('pubspec.yaml', yaml(contents));

/// Describes a file named `pubspec.yaml` for an application package with the
/// given [dependencies].
Descriptor appPubspec({Map? dependencies, Map<String, Object>? extras}) {
  final map = <String, Object>{
    'name': 'myapp',
    ...?extras,
  };
  if (dependencies != null) map['dependencies'] = dependencies;
  return pubspec(map);
}

/// Describes a file named `pubspec.yaml` for a library package with the given
/// [name], [version], and [deps]. If "sdk" is given, then it adds an SDK
/// constraint on that version, otherwise it adds an SDK constraint allowing
/// the current SDK version.
///
/// [extras] is additional fields of the pubspec.
FileDescriptor libPubspec(
  String name,
  String version, {
  Map<String, Object?>? deps,
  Map<String, Object?>? devDeps,
  String? sdk,
  Map<String, Object?>? extras,
  bool resolutionWorkspace = false,
}) {
  final map = packageMap(name, version, deps, devDeps);
  if (resolutionWorkspace && sdk == null) {
    sdk = '^3.5.0-0';
  }
  if (sdk != null) {
    map['environment'] = {'sdk': sdk};
  }
  return pubspec(
    {
      ...map,
      if (resolutionWorkspace) 'resolution': 'workspace',
      ...extras ?? {},
    },
  );
}

/// Describes a file named `pubspec_overrides.yaml` by default, with the given
/// YAML-serialized [contents], which should be a serializable object.
///
/// [contents] may contain [Future]s that resolve to serializable objects,
/// which may in turn contain [Future]s recursively.
Descriptor pubspecOverrides(Map<String, Object> contents) => YamlDescriptor(
      'pubspec_overrides.yaml',
      yaml(contents),
    );

/// Describes a directory named `lib` containing a single dart file named
/// `<name>.dart` that contains a line of Dart code.
Descriptor libDir(String name, [String? code]) {
  // Default to printing the name if no other code was given.
  code ??= name;
  return dir('lib', [file('$name.dart', 'main() => "$code";')]);
}

/// Describes a directory whose name ends with a hyphen followed by an
/// alphanumeric hash.
Descriptor hashDir(String name, Iterable<Descriptor> contents) => pattern(
      RegExp("$name${r'-[a-f0-9]+'}"),
      (dirName) => dir(dirName, contents),
    );

/// Describes a directory for a Git repo with a dart package.
/// This directory is of the form found in the revision cache of the global
/// package cache.
///
/// If [repoName] is not given it is assumed to be equal to [packageName].
Descriptor gitPackageRevisionCacheDir(
  String packageName, {
  int? modifier,
  String? repoName,
}) {
  repoName = repoName ?? packageName;
  var value = packageName;
  if (modifier != null) value = '$packageName $modifier';
  return hashDir(repoName, [libDir(packageName, value)]);
}

/// Describes a directory for a Git package. This directory is of the form
/// found in the repo cache of the global package cache.
Descriptor gitPackageRepoCacheDir(String name) =>
    hashDir(name, [dir('objects'), dir('refs')]);

/// Describes the global package cache directory containing all the given
/// [packages], which should be name/version pairs. The packages will be
/// validated against the format produced by the mock package server.
///
/// A package's value may also be a list of versions, in which case all
/// versions are expected to be downloaded.
///
/// If [port] is passed, it's used as the port number of the local hosted server
/// that this cache represents. It defaults to `globalServer.port`.
///
/// If [includePubspecs] is `true`, then pubspecs will be created for each
/// package. Defaults to `false` so that the contents of pubspecs are not
/// validated since they will often lack the dependencies section that the
/// real pubspec being compared against has. You usually only need to pass
/// `true` for this if you plan to call `create()` on the resulting descriptor.
Descriptor cacheDir(
  Map<String, dynamic> packages, {
  int? port,
  bool includePubspecs = false,
}) {
  final contents = <Descriptor>[];
  packages.forEach((name, versions) {
    if (versions is! List) versions = [versions];
    for (var version in versions) {
      final packageContents = [libDir(name, '$name $version')];
      if (includePubspecs) {
        packageContents.add(libPubspec(name, version as String));
      }
      contents.add(dir('$name-$version', packageContents));
    }
  });

  return hostedCache(contents, port: port);
}

/// Describes the main cache directory containing cached hosted packages
/// downloaded from the mock package server.
///
/// If [port] is passed, it's used as the port number of the local hosted server
/// that this cache represents. It defaults to `globalServer.port`.
Descriptor hostedCache(Iterable<Descriptor> contents, {int? port}) {
  return dir(hostedCachePath(port: port), contents);
}

/// Describes the hosted-hashes cache directory containing hashes of the hosted
/// packages downloaded from the mock package server.
///
/// If [port] is passed, it's used as the port number of the local hosted server
/// that this cache represents. It defaults to `globalServer.port`.
Descriptor hostedHashesCache(Iterable<Descriptor> contents, {int? port}) {
  return dir(cachePath, [
    dir(
      'hosted-hashes',
      [dir('localhost%58${port ?? globalServer.port}', contents)],
    ),
  ]);
}

String hostedCachePath({int? port}) =>
    p.join(cachePath, 'hosted', 'localhost%58${port ?? globalServer.port}');

/// Describes the file that contains the client's OAuth2
/// credentials. The URL "/token" on [server] will be used as the token
/// endpoint for refreshing the access token.
Descriptor credentialsFile(
  PackageServer server,
  String accessToken, {
  String? refreshToken,
  DateTime? expiration,
}) {
  return configDir(
    [
      file(
        'pub-credentials.json',
        _credentialsFileContent(
          server,
          accessToken,
          refreshToken: refreshToken,
          expiration: expiration,
        ),
      ),
    ],
  );
}

Descriptor legacyCredentialsFile(
  PackageServer server,
  String accessToken, {
  String? refreshToken,
  DateTime? expiration,
}) {
  return dir(
    cachePath,
    [
      file(
        'credentials.json',
        _credentialsFileContent(
          server,
          accessToken,
          refreshToken: refreshToken,
          expiration: expiration,
        ),
      ),
    ],
  );
}

String _credentialsFileContent(
  PackageServer server,
  String accessToken, {
  String? refreshToken,
  DateTime? expiration,
}) =>
    Credentials(
      accessToken,
      refreshToken: refreshToken,
      tokenEndpoint: Uri.parse(server.url).resolve('/token'),
      scopes: [
        'openid',
        'https://www.googleapis.com/auth/userinfo.email',
      ],
      expiration: expiration,
    ).toJson();

/// Describes the file in the system cache that contains credentials for
/// third party hosted pub servers.
Descriptor tokensFile([Map<String, dynamic> contents = const {}]) {
  return configDir([file('pub-tokens.json', jsonEncode(contents))]);
}

/// Describes the application directory, containing only a pubspec specifying
/// the given [dependencies].
DirectoryDescriptor appDir({Map? dependencies, Map<String, Object>? pubspec}) =>
    dir(appPath, [appPubspec(dependencies: dependencies, extras: pubspec)]);

/// Describes a `.dart_tools/package_config.json` file.
///
/// [packages] is a list of packages included in the file.
///
/// Validation checks that the `.dart_tools/package_config.json` file exists,
/// has the expected entries (one per key in [packages]), each with a path
/// that matches the `rootUri` of that package.
Descriptor packageConfigFile(
  List<PackageConfigEntry> packages, {
  String generatorVersion = '3.1.2+3',
  String? pubCache,
  String? flutterVersion,
  String? flutterRoot,
}) =>
    PackageConfigFileDescriptor(
      packages,
      generatorVersion,
      pubCache ??
          p.join(
            sandbox,
            cachePath,
          ),
      flutterRoot,
      flutterVersion,
    );

Descriptor appPackageConfigFile(
  List<PackageConfigEntry> packages, {
  String generatorVersion = '3.1.2+3',
  String? flutterRoot,
  String? flutterVersion,
}) =>
    dir(
      appPath,
      [
        packageConfigFile(
          [
            packageConfigEntry(name: 'myapp', path: '.'),
            ...packages,
          ],
          generatorVersion: generatorVersion,
          flutterRoot: flutterRoot,
          flutterVersion: flutterVersion,
        ),
      ],
    );

/// Create a [PackageConfigEntry] which assumes package with [name] is either
/// a cached package with given [version] or a path dependency at given [path].
PackageConfigEntry packageConfigEntry({
  required String name,
  String? version,
  String? path,
  String? languageVersion,
  PackageServer? server,
}) {
  if (version == null && path == null) {
    throw ArgumentError.value(
      version,
      'version',
      'Either "version" or "path" must be given',
    );
  }
  Uri rootUri;
  if (path == null && version != null) {
    rootUri = p.toUri((server ?? globalServer).pathInCache(name, version));
  } else {
    rootUri = p.toUri(p.join('..', path));
  }
  return PackageConfigEntry(
    name: name,
    rootUri: rootUri,
    packageUri: Uri(path: 'lib/'),
    languageVersion:
        languageVersion != null ? LanguageVersion.parse(languageVersion) : null,
  );
}

Descriptor flutterVersion(String version) {
  return dir('bin', [
    dir(
      'cache',
      [file('flutter.version.json', '{"flutterVersion":"$version"}')],
    ),
  ]);
}

/// Describes a file named `sdk_packages.yaml` at the root of the current SDK.
FileDescriptor sdkPackagesConfig(SdkPackageConfig sdkPackageConfig) {
  return YamlDescriptor('sdk_packages.yaml', yaml(sdkPackageConfig.toMap()));
}
