// 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.

// @dart = 2.8

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/license_collector.dart';
import 'package:package_config/package_config.dart';

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

const String _kMitLicense = r'''
MIT License

Copyright (c) 6789 Lester

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
''';

const String _kApacheLicense = r'''
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 1234 Tester

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
''';

void main() {
  FileSystem fileSystem;
  LicenseCollector licenseCollector;

  setUp(() {
    fileSystem = MemoryFileSystem.test();
    licenseCollector = LicenseCollector(fileSystem: fileSystem);
  });

  testWithoutContext('processes dependent licenses according to instructions', () async {
    fileSystem.file('foo/NOTICES')
      ..createSync(recursive: true)
      ..writeAsStringSync(_kMitLicense);
    fileSystem.file('bar/NOTICES')
      ..createSync(recursive: true)
      ..writeAsStringSync(_kApacheLicense);
    // NOTICES is preferred over LICENSE
    fileSystem.file('bar/LICENSE')
      ..createSync(recursive: true)
      ..writeAsStringSync('SHOULD NOT BE INCLUDED');
    fileSystem.file('fizz/LICENSE')
      ..createSync(recursive: true)
      ..writeAsStringSync(_kMitLicense); // intentionally a duplicate

    final File packageConfigFile = fileSystem.file('package_config.json')
      ..writeAsStringSync(json.encode(
        <String, Object>{
          'configVersion': 2,
          'packages': <Object>[
            <String, Object>{
              'name': 'foo',
              'rootUri': 'file:///foo/',
              'packageUri': 'lib/',
              'languageVersion': '2.2'
            },
            <String, Object>{
              'name': 'bar',
              'rootUri': 'file:///bar/',
              'packageUri': 'lib/',
              'languageVersion': '2.2'
            },
            <String, Object>{
              'name': 'fizz',
              'rootUri': 'file:///fizz/',
              'packageUri': 'lib/',
              'languageVersion': '2.2'
            },
          ],
        }
      ));
    final PackageConfig packageConfig = await loadPackageConfig(packageConfigFile.absolute);
    final LicenseResult result = licenseCollector.obtainLicenses(packageConfig, <String, List<File>>{});

    // All included licenses are combined in the result.
    expect(result.combinedLicenses, contains(_kApacheLicense));
    expect(result.combinedLicenses, contains(_kMitLicense));

    // String from LICENSE file was not included when NOTICES exists.
    expect(result.combinedLicenses, isNot(contains('SHOULD NOT BE INCLUDED')));

    // Licenses are de-duplicated correctly.
    expect(result.combinedLicenses.split(LicenseCollector.licenseSeparator), hasLength(2));

    // All input licenses included in result.
    final Iterable<String> filePaths = result.dependencies.map((File file) => file.path);
    expect(filePaths, unorderedEquals(<String>[
      '/foo/NOTICES',
      '/bar/NOTICES',
      '/fizz/LICENSE'
    ]));
  });

  testWithoutContext('includes additional LICENSE files as specified by pubspec.yaml', () async {
    fileSystem.file('foo/NOTICES')
        ..createSync(recursive: true)
        ..writeAsStringSync(_kMitLicense);
    fileSystem.file('bar/NOTICES')
      ..createSync(recursive: true)
      ..writeAsStringSync(_kApacheLicense);
    fileSystem.file('foo.txt').writeAsStringSync('foo.txt');
    fileSystem.file('bar.txt').writeAsStringSync('bar.txt');

    final File packageConfigFile = fileSystem.file('package_config.json')
      ..writeAsStringSync(json.encode(
        <String, Object>{
          'configVersion': 2,
          'packages': <Object>[
            <String, Object>{
              'name': 'foo',
              'rootUri': 'file:///foo/',
              'packageUri': 'lib/',
              'languageVersion': '2.2'
            },
            <String, Object>{
              'name': 'bar',
              'rootUri': 'file:///bar/',
              'packageUri': 'lib/',
              'languageVersion': '2.2'
            },
          ],
        }
      ));
    final PackageConfig packageConfig = await loadPackageConfig(packageConfigFile.absolute);
    final LicenseResult result = licenseCollector.obtainLicenses(packageConfig, <String, List<File>>{
      'foo': <File>[fileSystem.file('foo.txt').absolute],
      'bar': <File>[fileSystem.file('bar.txt').absolute],
    });

    // Additional license files are included in the result.
    expect(result.combinedLicenses, contains(_kApacheLicense));
    expect(result.combinedLicenses, contains(_kMitLicense));
    expect(result.combinedLicenses, contains('foo.txt'));
    expect(result.combinedLicenses, contains('bar.txt'));

    // All input licenses included in result.
    final Iterable<String> filePaths = result.dependencies.map((File file) => file.path);
    expect(filePaths, unorderedEquals(<String>[
      '/foo/NOTICES',
      '/bar/NOTICES',
      '/foo.txt',
      '/bar.txt',
    ]));
  });

  testWithoutContext('Returns a LicenseResult with an error message if an additional LICENSE file does not exist', () async {
    fileSystem.file('foo/NOTICES')
      ..createSync(recursive: true)
      ..writeAsStringSync(_kMitLicense);

    final File packageConfigFile = fileSystem.file('package_config.json')
      ..writeAsStringSync(json.encode(
        <String, Object>{
          'configVersion': 2,
          'packages': <Object>[
            <String, Object>{
              'name': 'foo',
              'rootUri': 'file:///foo/',
              'packageUri': 'lib/',
              'languageVersion': '2.2'
            },
          ],
        }
      ));
    final PackageConfig packageConfig = await loadPackageConfig(packageConfigFile.absolute);

    final LicenseResult licenseResult = licenseCollector.obtainLicenses(packageConfig, <String, List<File>>{
      'foo': <File>[fileSystem.file('foo.txt').absolute, fileSystem.file('foo_2.txt').absolute], // Files do not exist.
    });

    expect(licenseResult.combinedLicenses, '');
    expect(licenseResult.dependencies, isEmpty);
    expect(licenseResult.errorMessages, <String>[
      'package foo specified an additional license at /foo.txt, but this file does not exist.',
      'package foo specified an additional license at /foo_2.txt, but this file does not exist.'
    ]);
  });

  testWithoutContext('Returns a LicenseResult with an error message if an additional license file is not valid utf8', () async {
    fileSystem.file('foo/NOTICES')
      ..createSync(recursive: true)
      ..writeAsStringSync(_kMitLicense);
    fileSystem.file('foo.txt')
      ..createSync(recursive: true)
      ..writeAsBytesSync(<int>[0xFFFE]);

    final File packageConfigFile = fileSystem.file('package_config.json')
      ..writeAsStringSync(json.encode(
        <String, Object>{
          'configVersion': 2,
          'packages': <Object>[
            <String, Object>{
              'name': 'foo',
              'rootUri': 'file:///foo/',
              'packageUri': 'lib/',
              'languageVersion': '2.2'
            },
          ],
        }
      ));
    final PackageConfig packageConfig = await loadPackageConfig(packageConfigFile.absolute);

    final LicenseResult licenseResult = licenseCollector.obtainLicenses(packageConfig, <String, List<File>>{
      'foo': <File>[fileSystem.file('foo.txt').absolute],
    });

    expect(licenseResult.combinedLicenses, '');
    expect(licenseResult.dependencies, isEmpty);
    expect(licenseResult.errorMessages.single,
      'package foo specified an additional license at /foo.txt, but this file could not be read:'
      '\nFileSystemException: Invalid UTF-8 byte, path = \'/foo.txt\'',
    );
  });
}
