// 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,
        fileSystem,
        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.
''';
