// 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:meta/meta.dart';
import 'package:package_config/package_config.dart';

import 'base/file_system.dart';

/// Processes dependencies into a string representing the NOTICES file.
///
/// Reads the NOTICES or LICENSE file from each package in the .packages file,
/// splitting each one into each component license so that it can be de-duped
/// if possible. If the NOTICES file exists, it is preferred over the LICENSE
/// file.
///
/// Individual licenses inside each LICENSE file should be separated by 80
/// hyphens on their own on a line.
///
/// If a LICENSE or NOTICES file contains more than one component license,
/// then each component license must start with the names of the packages to
/// which the component license applies, with each package name on its own line
/// and the list of package names separated from the actual license text by a
/// blank line. The packages need not match the names of the pub package. For
/// example, a package might itself contain code from multiple third-party
/// sources, and might need to include a license for each one.
class LicenseCollector {
  LicenseCollector({
    @required FileSystem fileSystem
  }) : _fileSystem = fileSystem;

  final FileSystem _fileSystem;

  /// The expected separator for multiple licenses.
  static final String licenseSeparator = '\n' + ('-' * 80) + '\n';

  /// Obtain licenses from the `packageMap` into a single result.
  ///
  /// [additionalLicenses] should contain aggregated license files from all
  /// of the current applications dependencies.
  LicenseResult obtainLicenses(
    PackageConfig packageConfig,
    Map<String, List<File>> additionalLicenses,
  ) {
    final Map<String, Set<String>> packageLicenses = <String, Set<String>>{};
    final Set<String> allPackages = <String>{};
    final List<File> dependencies = <File>[];

    for (final Package package in packageConfig.packages) {
      final Uri packageUri = package.packageUriRoot;
      if (packageUri == null || packageUri.scheme != 'file') {
        continue;
      }
      // First check for NOTICES, then fallback to LICENSE
      File file = _fileSystem.file(packageUri.resolve('../NOTICES'));
      if (!file.existsSync()) {
        file = _fileSystem.file(packageUri.resolve('../LICENSE'));
      }
      if (!file.existsSync()) {
        continue;
      }

      dependencies.add(file);
      final List<String> rawLicenses = file
        .readAsStringSync()
        .split(licenseSeparator);
      for (final String rawLicense in rawLicenses) {
        List<String> packageNames;
        String licenseText;
        if (rawLicenses.length > 1) {
          final int split = rawLicense.indexOf('\n\n');
          if (split >= 0) {
            packageNames = rawLicense.substring(0, split).split('\n');
            licenseText = rawLicense.substring(split + 2);
          }
        }
        if (licenseText == null) {
          packageNames = <String>[package.name];
          licenseText = rawLicense;
        }
        packageLicenses.putIfAbsent(licenseText, () => <String>{}).addAll(packageNames);
        allPackages.addAll(packageNames);
      }
    }

    final List<String> combinedLicensesList = packageLicenses.keys
      .map<String>((String license) {
        final List<String> packageNames = packageLicenses[license].toList()
          ..sort();
        return packageNames.join('\n') + '\n\n' + license;
      }).toList();
    combinedLicensesList.sort();

    /// Append additional LICENSE files as specified in the pubspec.yaml.
    final List<String> additionalLicenseText = <String>[];
    final List<String> errorMessages = <String>[];
    for (final String package in additionalLicenses.keys) {
      for (final File license in additionalLicenses[package]) {
        if (!license.existsSync()) {
          errorMessages.add(
            'package $package specified an additional license at ${license.path}, but this file '
            'does not exist.'
          );
          continue;
        }
        dependencies.add(license);
        try {
          additionalLicenseText.add(license.readAsStringSync());
        } on FormatException catch (err) {
          // File has an invalid encoding.
          errorMessages.add(
            'package $package specified an additional license at ${license.path}, but this file '
            'could not be read:\n$err'
          );
        } on FileSystemException catch (err) {
          // File cannot be parsed.
          errorMessages.add(
            'package $package specified an additional license at ${license.path}, but this file '
            'could not be read:\n$err'
          );
        }
      }
    }
    if (errorMessages.isNotEmpty) {
      return LicenseResult(
        combinedLicenses: '',
        dependencies: <File>[],
        errorMessages: errorMessages,
      );
    }

    final String combinedLicenses = combinedLicensesList
      .followedBy(additionalLicenseText)
      .join(licenseSeparator);

    return LicenseResult(
      combinedLicenses: combinedLicenses,
      dependencies: dependencies,
      errorMessages: errorMessages,
    );
  }
}

/// The result of processing licenses with a [LicenseCollector].
class LicenseResult {
  const LicenseResult({
    @required this.combinedLicenses,
    @required this.dependencies,
    @required this.errorMessages,
  });

  /// The raw text of the consumed licenses.
  final String combinedLicenses;

  /// Each license file that was consumed as input.
  final List<File> dependencies;

  /// If non-empty, license collection failed and this messages should
  /// be displayed by the asset parser.
  final List<String> errorMessages;
}
