// Copyright 2013 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:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common.dart';
import 'package:flutter_plugin_tools/src/license_check_command.dart';
import 'package:test/test.dart';

void main() {
  group('$LicenseCheckCommand', () {
    late CommandRunner<void> runner;
    late FileSystem fileSystem;
    late List<String> printedMessages;
    late Directory root;

    setUp(() {
      fileSystem = MemoryFileSystem();
      final Directory packagesDir =
          fileSystem.currentDirectory.childDirectory('packages');
      root = packagesDir.parent;

      printedMessages = <String>[];
      final LicenseCheckCommand command = LicenseCheckCommand(
        packagesDir,
        print: (Object? message) => printedMessages.add(message.toString()),
      );
      runner =
          CommandRunner<void>('license_test', 'Test for $LicenseCheckCommand');
      runner.addCommand(command);
    });

    /// Writes a copyright+license block to [file], defaulting to a standard
    /// block for this repository.
    ///
    /// [commentString] is added to the start of each line.
    /// [prefix] is added to the start of the entire block.
    /// [suffix] is added to the end of the entire block.
    void _writeLicense(
      File file, {
      String comment = '// ',
      String prefix = '',
      String suffix = '',
      String copyright =
          'Copyright 2013 The Flutter Authors. All rights reserved.',
      List<String> license = const <String>[
        'Use of this source code is governed by a BSD-style license that can be',
        'found in the LICENSE file.',
      ],
    }) {
      final List<String> lines = <String>['$prefix$comment$copyright'];
      for (final String line in license) {
        lines.add('$comment$line');
      }
      file.writeAsStringSync(lines.join('\n') + suffix + '\n');
    }

    test('looks at only expected extensions', () async {
      final Map<String, bool> extensions = <String, bool>{
        'c': true,
        'cc': true,
        'cpp': true,
        'dart': true,
        'h': true,
        'html': true,
        'java': true,
        'json': false,
        'm': true,
        'md': false,
        'mm': true,
        'png': false,
        'swift': true,
        'sh': true,
        'yaml': false,
      };

      const String filenameBase = 'a_file';
      for (final String fileExtension in extensions.keys) {
        root.childFile('$filenameBase.$fileExtension').createSync();
      }

      try {
        await runner.run(<String>['license-check']);
      } on ToolExit {
        // Ignore failure; the files are empty so the check is expected to fail,
        // but this test isn't for that behavior.
      }

      extensions.forEach((String fileExtension, bool shouldCheck) {
        final Matcher logLineMatcher =
            contains('Checking $filenameBase.$fileExtension');
        expect(printedMessages,
            shouldCheck ? logLineMatcher : isNot(logLineMatcher));
      });
    });

    test('ignore list overrides extension matches', () async {
      final List<String> ignoredFiles = <String>[
        // Ignored base names.
        'flutter_export_environment.sh',
        'GeneratedPluginRegistrant.java',
        'GeneratedPluginRegistrant.m',
        'generated_plugin_registrant.cc',
        'generated_plugin_registrant.cpp',
        // Ignored path suffixes.
        'foo.g.dart',
        'foo.mocks.dart',
        // Ignored files.
        'resource.h',
      ];

      for (final String name in ignoredFiles) {
        root.childFile(name).createSync();
      }

      await runner.run(<String>['license-check']);

      for (final String name in ignoredFiles) {
        expect(printedMessages, isNot(contains('Checking $name')));
      }
    });

    test('passes if all checked files have license blocks', () async {
      final File checked = root.childFile('checked.cc');
      checked.createSync();
      _writeLicense(checked);
      final File notChecked = root.childFile('not_checked.md');
      notChecked.createSync();

      await runner.run(<String>['license-check']);

      // Sanity check that the test did actually check a file.
      expect(printedMessages, contains('Checking checked.cc'));
      expect(printedMessages, contains('All source files passed validation!'));
    });

    test('handles the comment styles for all supported languages', () async {
      final File fileA = root.childFile('file_a.cc');
      fileA.createSync();
      _writeLicense(fileA, comment: '// ');
      final File fileB = root.childFile('file_b.sh');
      fileB.createSync();
      _writeLicense(fileB, comment: '# ');
      final File fileC = root.childFile('file_c.html');
      fileC.createSync();
      _writeLicense(fileC, comment: '', prefix: '<!-- ', suffix: ' -->');

      await runner.run(<String>['license-check']);

      // Sanity check that the test did actually check the files.
      expect(printedMessages, contains('Checking file_a.cc'));
      expect(printedMessages, contains('Checking file_b.sh'));
      expect(printedMessages, contains('Checking file_c.html'));
      expect(printedMessages, contains('All source files passed validation!'));
    });

    test('fails if any checked files are missing license blocks', () async {
      final File goodA = root.childFile('good.cc');
      goodA.createSync();
      _writeLicense(goodA);
      final File goodB = root.childFile('good.h');
      goodB.createSync();
      _writeLicense(goodB);
      root.childFile('bad.cc').createSync();
      root.childFile('bad.h').createSync();

      await expectLater(() => runner.run(<String>['license-check']),
          throwsA(const TypeMatcher<ToolExit>()));

      // Failure should give information about the problematic files.
      expect(
          printedMessages,
          contains(
              'The license block for these files is missing or incorrect:'));
      expect(printedMessages, contains('  bad.cc'));
      expect(printedMessages, contains('  bad.h'));
      // Failure shouldn't print the success message.
      expect(printedMessages,
          isNot(contains('All source files passed validation!')));
    });

    test('fails if any checked files are missing just the copyright', () async {
      final File good = root.childFile('good.cc');
      good.createSync();
      _writeLicense(good);
      final File bad = root.childFile('bad.cc');
      bad.createSync();
      _writeLicense(bad, copyright: '');

      await expectLater(() => runner.run(<String>['license-check']),
          throwsA(const TypeMatcher<ToolExit>()));

      // Failure should give information about the problematic files.
      expect(
          printedMessages,
          contains(
              'The license block for these files is missing or incorrect:'));
      expect(printedMessages, contains('  bad.cc'));
      // Failure shouldn't print the success message.
      expect(printedMessages,
          isNot(contains('All source files passed validation!')));
    });

    test('fails if any checked files are missing just the license', () async {
      final File good = root.childFile('good.cc');
      good.createSync();
      _writeLicense(good);
      final File bad = root.childFile('bad.cc');
      bad.createSync();
      _writeLicense(bad, license: <String>[]);

      await expectLater(() => runner.run(<String>['license-check']),
          throwsA(const TypeMatcher<ToolExit>()));

      // Failure should give information about the problematic files.
      expect(
          printedMessages,
          contains(
              'The license block for these files is missing or incorrect:'));
      expect(printedMessages, contains('  bad.cc'));
      // Failure shouldn't print the success message.
      expect(printedMessages,
          isNot(contains('All source files passed validation!')));
    });

    test('fails if any third-party code is not in a third_party directory',
        () async {
      final File thirdPartyFile = root.childFile('third_party.cc');
      thirdPartyFile.createSync();
      _writeLicense(thirdPartyFile, copyright: 'Copyright 2017 Someone Else');

      await expectLater(() => runner.run(<String>['license-check']),
          throwsA(const TypeMatcher<ToolExit>()));

      // Failure should give information about the problematic files.
      expect(
          printedMessages,
          contains(
              'The license block for these files is missing or incorrect:'));
      expect(printedMessages, contains('  third_party.cc'));
      // Failure shouldn't print the success message.
      expect(printedMessages,
          isNot(contains('All source files passed validation!')));
    });

    test('succeeds for third-party code in a third_party directory', () async {
      final File thirdPartyFile = root
          .childDirectory('a_plugin')
          .childDirectory('lib')
          .childDirectory('src')
          .childDirectory('third_party')
          .childFile('file.cc');
      thirdPartyFile.createSync(recursive: true);
      _writeLicense(thirdPartyFile,
          copyright: 'Copyright 2017 Workiva Inc.',
          license: <String>[
            'Licensed under the Apache License, Version 2.0 (the "License");',
            'you may not use this file except in compliance with the License.'
          ]);

      await runner.run(<String>['license-check']);

      // Sanity check that the test did actually check the file.
      expect(printedMessages,
          contains('Checking a_plugin/lib/src/third_party/file.cc'));
      expect(printedMessages, contains('All source files passed validation!'));
    });

    test('allows first-party code in a third_party directory', () async {
      final File firstPartyFileInThirdParty = root
          .childDirectory('a_plugin')
          .childDirectory('lib')
          .childDirectory('src')
          .childDirectory('third_party')
          .childFile('first_party.cc');
      firstPartyFileInThirdParty.createSync(recursive: true);
      _writeLicense(firstPartyFileInThirdParty);

      await runner.run(<String>['license-check']);

      // Sanity check that the test did actually check the file.
      expect(printedMessages,
          contains('Checking a_plugin/lib/src/third_party/first_party.cc'));
      expect(printedMessages, contains('All source files passed validation!'));
    });

    test('fails for licenses that the tool does not expect', () async {
      final File good = root.childFile('good.cc');
      good.createSync();
      _writeLicense(good);
      final File bad = root.childDirectory('third_party').childFile('bad.cc');
      bad.createSync(recursive: true);
      _writeLicense(bad, license: <String>[
        'This program is free software: you can redistribute it and/or modify',
        'it under the terms of the GNU General Public License',
      ]);

      await expectLater(() => runner.run(<String>['license-check']),
          throwsA(const TypeMatcher<ToolExit>()));

      // Failure should give information about the problematic files.
      expect(
          printedMessages,
          contains(
              'No recognized license was found for the following third-party files:'));
      expect(printedMessages, contains('  third_party/bad.cc'));
      // Failure shouldn't print the success message.
      expect(printedMessages,
          isNot(contains('All source files passed validation!')));
    });

    test('Apache is not recognized for new authors without validation changes',
        () async {
      final File good = root.childFile('good.cc');
      good.createSync();
      _writeLicense(good);
      final File bad = root.childDirectory('third_party').childFile('bad.cc');
      bad.createSync(recursive: true);
      _writeLicense(
        bad,
        copyright: 'Copyright 2017 Some New Authors.',
        license: <String>[
          'Licensed under the Apache License, Version 2.0 (the "License");',
          'you may not use this file except in compliance with the License.'
        ],
      );

      await expectLater(() => runner.run(<String>['license-check']),
          throwsA(const TypeMatcher<ToolExit>()));

      // Failure should give information about the problematic files.
      expect(
          printedMessages,
          contains(
              'No recognized license was found for the following third-party files:'));
      expect(printedMessages, contains('  third_party/bad.cc'));
      // Failure shouldn't print the success message.
      expect(printedMessages,
          isNot(contains('All source files passed validation!')));
    });

    test('passes if all first-party LICENSE files are correctly formatted',
        () async {
      final File license = root.childFile('LICENSE');
      license.createSync();
      license.writeAsStringSync(_correctLicenseFileText);

      await runner.run(<String>['license-check']);

      // Sanity check that the test did actually check the file.
      expect(printedMessages, contains('Checking LICENSE'));
      expect(printedMessages, contains('All LICENSE files passed validation!'));
    });

    test('fails if any first-party LICENSE files are incorrectly formatted',
        () async {
      final File license = root.childFile('LICENSE');
      license.createSync();
      license.writeAsStringSync(_incorrectLicenseFileText);

      await expectLater(() => runner.run(<String>['license-check']),
          throwsA(const TypeMatcher<ToolExit>()));

      expect(printedMessages,
          isNot(contains('All LICENSE files passed validation!')));
    });

    test('ignores third-party LICENSE format', () async {
      final File license =
          root.childDirectory('third_party').childFile('LICENSE');
      license.createSync(recursive: true);
      license.writeAsStringSync(_incorrectLicenseFileText);

      await runner.run(<String>['license-check']);

      // The file shouldn't be checked.
      expect(printedMessages, isNot(contains('Checking third_party/LICENSE')));
      expect(printedMessages, contains('All LICENSE files passed validation!'));
    });
  });
}

const String _correctLicenseFileText = '''
Copyright 2013 The Flutter Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.
    * Neither the name of Google Inc. nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
''';

// A common incorrect version created by copying text intended for a code file,
// with comment markers.
const String _incorrectLicenseFileText = '''
// Copyright 2013 The Flutter Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
''';
