// Copyright 2014 The Flutter Authors. 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:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/commands/update_packages.dart';

import '../src/common.dart';

// An example pubspec.yaml from flutter, not necessary for it to be up to date.
const String kFlutterPubspecYaml = r'''
name: flutter
description: A framework for writing Flutter applications
homepage: http://flutter.dev

environment:
  sdk: '>=2.2.2 <4.0.0'

dependencies:
  # To update these, use "flutter update-packages --force-upgrade".
  collection: 1.14.11
  meta: 1.1.8
  typed_data: 1.1.6
  vector_math: 2.0.8

  sky_engine:
    sdk: flutter

  gallery:
    git:
      url: https://github.com/flutter/gallery.git
      ref: d00362e6bdd0f9b30bba337c358b9e4a6e4ca950

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_goldens:
    sdk: flutter

  archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"

# PUBSPEC CHECKSUM: 1437
''';

const String kExtraPubspecYaml = r'''
name: nodeps
description: A dummy pubspec with no dependencies
homepage: http://flutter.dev

environment:
  sdk: ">=2.2.2 <4.0.0"
''';

const String kInvalidGitPubspec = '''
name: flutter
description: A framework for writing Flutter applications
homepage: http://flutter.dev

environment:
  sdk: ">=2.2.2 <4.0.0"

dependencies:
  # To update these, use "flutter update-packages --force-upgrade".
  collection: 1.14.11
  meta: 1.1.8
  typed_data: 1.1.6
  vector_math: 2.0.8

  sky_engine:
    sdk: flutter

  gallery:
    git:
''';

void main() {
  late FileSystem fileSystem;
  late Directory flutterSdk;
  late Directory flutter;

  setUp(() {
    fileSystem = MemoryFileSystem.test();
    // Setup simplified Flutter SDK.
    flutterSdk = fileSystem.directory('flutter')..createSync();
    // Create version file
    flutterSdk.childFile('version').writeAsStringSync('1.2.3');
    // Create a pubspec file
    flutter = flutterSdk.childDirectory('packages').childDirectory('flutter')
      ..createSync(recursive: true);
    flutter.childFile('pubspec.yaml').writeAsStringSync(kFlutterPubspecYaml);
  });

  testWithoutContext('kManuallyPinnedDependencies pins are actually pins', () {
    expect(
      kManuallyPinnedDependencies.values,
      isNot(contains(anyOf('any', startsWith('^'), startsWith('>'), startsWith('<')))),
      reason: 'Version pins in kManuallyPinnedDependencies must be specific pins, not ranges.',
    );
    expect(
      kManuallyPinnedDependencies.keys,
      unorderedEquals(const <String>[
        'flutter_gallery_assets',
        'flutter_template_images',
        'video_player',
        'material_color_utilities',
        'url_launcher_android',
        'archive',
        'path_provider_android',
        'flutter_plugin_android_lifecycle',
      ]),
    );
  });

  testWithoutContext(
      'createTemporaryFlutterSdk creates an unpinned flutter SDK', () {
    // A stray extra package should not cause a crash.
    final Directory extra = flutterSdk
        .childDirectory('packages')
        .childDirectory('extra')
      ..createSync(recursive: true);
    extra.childFile('pubspec.yaml').writeAsStringSync(kExtraPubspecYaml);

    // Create already parsed pubspecs.
    final PubspecYaml flutterPubspec = PubspecYaml(flutter);

    final PubspecDependency gitDependency = flutterPubspec.dependencies
        .firstWhere((PubspecDependency dep) => dep.kind == DependencyKind.git);
    expect(
      gitDependency.lockLine,
      '''
    git:
      url: https://github.com/flutter/gallery.git
      ref: d00362e6bdd0f9b30bba337c358b9e4a6e4ca950
''',
    );
    final BufferLogger bufferLogger = BufferLogger.test();
    final Directory result = createTemporaryFlutterSdk(
      bufferLogger,
      fileSystem,
      flutterSdk,
      <PubspecYaml>[flutterPubspec],
      fileSystem.systemTempDirectory,
    );

    expect(result, exists);

    // We get a warning about the unexpected package.
    expect(
      bufferLogger.warningText,
      contains("Unexpected package 'extra' found in packages directory"),
    );

    // The version file exists.
    expect(result.childFile('version'), exists);
    expect(result.childFile('version').readAsStringSync(), '1.2.3');

    // The sky_engine package exists
    expect(fileSystem.directory('${result.path}/bin/cache/pkg/sky_engine'), exists);

    // The flutter pubspec exists
    final File pubspecFile = fileSystem.file('${result.path}/packages/flutter/pubspec.yaml');
    expect(pubspecFile, exists);

    // The flutter pubspec contains `any` dependencies.
    final PubspecYaml outputPubspec = PubspecYaml(pubspecFile.parent);
    expect(outputPubspec.name, 'flutter');
    expect(outputPubspec.dependencies.first.name, 'collection');
    expect(outputPubspec.dependencies.first.version, 'any');
  });

  testWithoutContext('Throws a StateError on a malformed git: reference', () {
    // Create an invalid pubspec file.
    flutter.childFile('pubspec.yaml').writeAsStringSync(kInvalidGitPubspec);

    expect(
      () => PubspecYaml(flutter),
      throwsStateError,
    );
  });

  testWithoutContext('PubspecYaml Loads dependencies', () async {
    final PubspecYaml pubspecYaml = PubspecYaml(flutter);
    expect(
        pubspecYaml.allDependencies
            .map<String>((PubspecDependency dependency) => '${dependency.name}: ${dependency.version}')
            .toSet(),
        equals(<String>{
          'collection: 1.14.11',
          'meta: 1.1.8',
          'typed_data: 1.1.6',
          'vector_math: 2.0.8',
          'sky_engine: ',
          'gallery: ',
          'flutter_test: ',
          'flutter_goldens: ',
          'archive: 2.0.11',
        }));
    expect(
        pubspecYaml.allExplicitDependencies
            .map<String>((PubspecDependency dependency) => '${dependency.name}: ${dependency.version}')
            .toSet(),
        equals(<String>{
          'collection: 1.14.11',
          'meta: 1.1.8',
          'typed_data: 1.1.6',
          'vector_math: 2.0.8',
          'sky_engine: ',
          'gallery: ',
          'flutter_test: ',
          'flutter_goldens: ',
        }));
    expect(
        pubspecYaml.dependencies
            .map<String>((PubspecDependency dependency) => '${dependency.name}: ${dependency.version}')
            .toSet(),
        equals(<String>{
          'collection: 1.14.11',
          'meta: 1.1.8',
          'typed_data: 1.1.6',
          'vector_math: 2.0.8',
          'sky_engine: ',
          'gallery: ',
        }));
  });
}
