// Copyright (c) 2017, 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:path/path.dart' as p;
import 'package:pub/src/validator.dart';
import 'package:pub/src/validator/strict_dependencies.dart';
import 'package:test/test.dart';

import '../descriptor.dart' as d;
import '../test_pub.dart';
import 'utils.dart';

Validator strictDeps() => StrictDependenciesValidator();

void main() {
  group('should consider a package valid if it', () {
    setUp(d.validPackage().create);

    test('looks normal', () => expectValidationDeprecated(strictDeps));

    test('declares an "import" as a dependency in lib/', () async {
      await d.dir(appPath, [
        d.libPubspec(
          'test_pkg',
          '1.0.0',
          deps: {'silly_monkey': '^1.2.3'},
          sdk: '>=1.8.0 <2.0.0',
        ),
        d.dir('lib', [
          d.file('library.dart', r'''
            import 'package:silly_monkey/silly_monkey.dart';
          '''),
        ]),
      ]).create();

      await expectValidationDeprecated(strictDeps);
    });

    test('declares an "export" as a dependency in lib/', () async {
      await d.dir(appPath, [
        d.libPubspec(
          'test_pkg',
          '1.0.0',
          deps: {'silly_monkey': '^1.2.3'},
          sdk: '>=1.8.0 <2.0.0',
        ),
        d.dir('lib', [
          d.file('library.dart', r'''
            export 'package:silly_monkey/silly_monkey.dart';
          '''),
        ]),
      ]).create();

      await expectValidationDeprecated(strictDeps);
    });

// Regression test of https://github.com/dart-lang/pub/issues/4115 .
    test('imports a dev_dependency in bindings_generator/', () async {
      await d.dir(appPath, [
        d.libPubspec(
          'test_pkg',
          '1.0.0',
          devDeps: {'silly_monkey': '^1.2.3'},
          sdk: '>=1.8.0 <2.0.0',
        ),
        d.dir('bindings_generator', [
          d.file('library.dart', r'''
            export 'package:silly_monkey/silly_monkey.dart';
          '''),
        ]),
      ]).create();

      await expectValidationDeprecated(strictDeps);
    });

    test('declares an "import" as a dependency in bin/', () async {
      await d.dir(appPath, [
        d.libPubspec(
          'test_pkg',
          '1.0.0',
          deps: {'silly_monkey': '^1.2.3'},
          sdk: '>=1.8.0 <2.0.0',
        ),
        d.dir('bin', [
          d.file('library.dart', r'''
            import 'package:silly_monkey/silly_monkey.dart';
          '''),
        ]),
      ]).create();

      await expectValidationDeprecated(strictDeps);
    });

    for (var port in ['import', 'export']) {
      for (var isDev in [false, true]) {
        Map<String, String>? deps;
        Map<String, String>? devDeps;

        if (isDev) {
          devDeps = {'silly_monkey': '^1.2.3'};
        } else {
          deps = {'silly_monkey': '^1.2.3'};
        }
        for (var devDir in ['benchmark', 'example', 'test', 'tool']) {
          test(
              'declares an "$port" as a '
              '${isDev ? 'dev ' : ''}dependency in $devDir/', () async {
            await d.dir(appPath, [
              d.libPubspec(
                'test_pkg',
                '1.0.0',
                deps: deps,
                devDeps: devDeps,
                sdk: '>=1.8.0 <2.0.0',
              ),
              d.dir(devDir, [
                d.file('library.dart', '''
            $port 'package:silly_monkey/silly_monkey.dart';
          '''),
              ]),
            ]).create();

            await expectValidationDeprecated(strictDeps);
          });
        }
      }
    }

    test('only uses dart: dependencies (not pub packages)', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        import 'dart:async';
        import 'dart:collection';
        import 'dart:typed_data';
      ''').create();

      await expectValidationDeprecated(strictDeps);
    });

    test('imports itself', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        import 'package:test_pkg/test_pkg.dart';
      ''').create();

      await expectValidationDeprecated(strictDeps);
    });

    test('has a relative import', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        import 'some/relative/path.dart';
      ''').create();

      await expectValidationDeprecated(strictDeps);
    });

    test('has an absolute import', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        import 'file://shared/some/library.dart';
      ''').create();

      await expectValidationDeprecated(strictDeps);
    });

    test('has a parse error preventing reading directives', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        import not_supported_keyword 'dart:async';
      ''').create();

      await expectValidationDeprecated(strictDeps);
    });

    test('has a top-level Dart file with an invalid dependency', () async {
      await d.file(p.join(appPath, 'top_level.dart'), r'''
        import 'package:';
      ''').create();

      await expectValidationDeprecated(strictDeps);
    });

    test('has a Dart-like file with an invalid dependency', () async {
      await d.file(p.join(appPath, 'lib', 'generator.dart.template'), r'''
        import 'package:';
      ''').create();

      await expectValidationDeprecated(strictDeps);
    });

    test('has analysis_options.yaml that excludes files', () async {
      await d.dir(appPath, [
        d.libPubspec(
          'test_pkg',
          '1.0.0',
          deps: {'silly_monkey': '^1.2.3'},
          sdk: '>=1.8.0 <2.0.0',
        ),
        d.dir('lib', [
          d.file('library.dart', r'''
            import 'package:silly_monkey/silly_monkey.dart';
          '''),
        ]),
        d.dir('test', [
          d.dir('data', [
            d.dir('mypkg', [
              d.dir('lib', [
                d.file('dummy.dart', '\n'),
              ]),
            ]),
          ]),
        ]),
        d.file('analysis_options.yaml', r'''analyzer:
  exclude:
    - test/data/**
linter:
  rules:
    - avoid_catching_errors
'''),
      ]).create();

      await expectValidationDeprecated(strictDeps);
    });

    test('has lib/analysis_options.yaml that excludes files', () async {
      await d.dir(appPath, [
        d.libPubspec(
          'test_pkg',
          '1.0.0',
          deps: {'silly_monkey': '^1.2.3'},
          sdk: '>=1.8.0 <2.0.0',
        ),
        d.dir('lib', [
          d.file('library.dart', r'''
            import 'package:silly_monkey/silly_monkey.dart';
          '''),
          d.file('analysis_options.yaml', r'''
analyzer:
  exclude:
    - '**'
linter:
  rules:
    - avoid_catching_errors
'''),
        ]),
        d.dir('test', [
          d.dir('data', [
            d.dir('mypkg', [
              d.dir('lib', [
                d.file('dummy.dart', '\n'),
              ]),
            ]),
          ]),
        ]),
      ]).create();

      await expectValidationDeprecated(strictDeps);
    });
  });

  group('should consider a package invalid if it', () {
    setUp(d.validPackage().create);

    test('has an invalid String value', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        import 'package:$bad';
      ''').create();

      await expectValidationDeprecated(
        strictDeps,
        errors: [matches('Invalid URL.')],
      );
    });

    test('does not declare an "import" as a dependency', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        import 'package:silly_monkey/silly_monkey.dart';
      ''').create();

      await expectValidationDeprecated(
        strictDeps,
        errors: [
          matches('does not have silly_monkey in the `dependencies` section'),
        ],
      );
    });

    test('hook does not declare an "import" as a dependency', () async {
      await d.dir(
        p.join(appPath, 'hook'),
        [
          d.file('build.dart', r'''
        import 'package:silly_monkey/silly_monkey.dart';
      '''),
        ],
      ).create();

      await expectValidationDeprecated(
        strictDeps,
        errors: [
          matches('does not have silly_monkey in the `dependencies` section'),
        ],
      );
    });

    test('hook declares an import as a devDependency for', () async {
      await d.dir(
        appPath,
        [
          d.libPubspec(
            'test_pkg',
            '1.0.0',
            devDeps: {'silly_monkey': '^1.2.3'},
            sdk: '>=1.8.0 <2.0.0',
          ),
          d.dir(
            'hook',
            [
              d.file('build.dart', r'''
        import 'package:silly_monkey/silly_monkey.dart';
      '''),
            ],
          ),
        ],
      ).create();

      await expectValidationDeprecated(
        strictDeps,
        errors: [
          matches(
            'silly_monkey is in the `dev_dependencies` section of '
            '`pubspec.yaml`',
          ),
        ],
      );
    });

    test('does not declare an "export" as a dependency', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        export 'package:silly_monkey/silly_monkey.dart';
      ''').create();

      await expectValidationDeprecated(
        strictDeps,
        errors: [
          matches('does not have silly_monkey in the `dependencies` section'),
        ],
      );
    });

    test('has an invalid URI', () async {
      await d.file(p.join(appPath, 'lib', 'library.dart'), r'''
        import 'package:/';
      ''').create();

      await expectValidationDeprecated(strictDeps, errors: isNotEmpty);
    });

    for (var port in ['import', 'export']) {
      for (var codeDir in ['bin', 'lib']) {
        test('declares an "$port" as a devDependency for $codeDir/', () async {
          await d.dir(appPath, [
            d.libPubspec(
              'test_pkg',
              '1.0.0',
              devDeps: {'silly_monkey': '^1.2.3'},
              sdk: '>=1.8.0 <2.0.0',
            ),
            d.dir(codeDir, [
              d.file('library.dart', '''
            $port 'package:silly_monkey/silly_monkey.dart';
          '''),
            ]),
          ]).create();

          await expectValidationDeprecated(strictDeps, errors: isNotEmpty);
        });
      }
    }

    for (var port in ['import', 'export']) {
      for (var devDir in ['benchmark', 'test', 'tool']) {
        test('does not declare an "$port" as a dependency in $devDir/',
            () async {
          await d.dir(appPath, [
            d.libPubspec('test_pkg', '1.0.0', sdk: '>=1.8.0 <2.0.0'),
            d.dir(devDir, [
              d.file('library.dart', '''
            $port 'package:silly_monkey/silly_monkey.dart';
          '''),
            ]),
          ]).create();

          await expectValidationDeprecated(
            strictDeps,
            warnings: [
              matches(
                'does not have silly_monkey in the '
                '`dependencies` or `dev_dependencies` section',
              ),
            ],
          );
        });
      }
    }

    group('declares an import with an invalid package URL: ', () {
      test('"package:"', () async {
        await d.dir(appPath, [
          d.dir('lib', [
            d.file('library.dart', r'''
            import 'package:';
          '''),
          ]),
        ]).create();

        await expectValidationDeprecated(strictDeps, errors: isNotEmpty);
      });

      test('"package:silly_monkey"', () async {
        await d.dir(appPath, [
          d.libPubspec(
            'test_pkg',
            '1.0.0',
            deps: {'silly_monkey': '^1.2.3'},
            sdk: '>=1.8.0 <2.0.0',
          ),
          d.dir('lib', [
            d.file('library.dart', r'''
            import 'package:silly_monkey';
          '''),
          ]),
        ]).create();

        await expectValidationDeprecated(strictDeps, errors: isNotEmpty);
      });

      test('"package:/"', () async {
        await d.dir(appPath, [
          d.dir('lib', [
            d.file('library.dart', r'''
            import 'package:/';
          '''),
          ]),
        ]).create();

        await expectValidationDeprecated(strictDeps, errors: isNotEmpty);
      });

      test('"package:/]"', () async {
        await d.dir(appPath, [
          d.dir('lib', [
            d.file('library.dart', r'''
            import 'package:/]';
          '''),
          ]),
        ]).create();

        await expectValidationDeprecated(strictDeps, errors: isNotEmpty);
      });
    });
  });
}
