// 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:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/package_meta.dart';
import 'package:dartdoc/src/tuple.dart';

abstract class PackageWarningOptionContext implements DartdocOptionContextBase {
  bool get allowNonLocalWarnings =>
      optionSet['allowNonLocalWarnings'].valueAt(context);

  // allowWarningsInPackages, ignoreWarningsInPackages, errors, warnings, and ignore
  // are only used indirectly via the synthetic packageWarningOptions option.
  PackageWarningOptions get packageWarningOptions =>
      optionSet['packageWarningOptions'].valueAt(context);

  bool get verboseWarnings => optionSet['verboseWarnings'].valueAt(context);
}

Future<List<DartdocOption<Object>>> createPackageWarningOptions(
  PackageMetaProvider packageMetaProvider,
) async {
  var resourceProvider = packageMetaProvider.resourceProvider;
  return [
    DartdocOptionArgOnly<bool>('allowNonLocalWarnings', false, resourceProvider,
        negatable: true,
        help: 'Show warnings from packages we are not documenting locally.'),

    // Options for globally enabling/disabling all warnings and errors
    // for individual packages are command-line only.  This will allow
    // meta-packages like Flutter to control whether warnings are displayed for
    // packages they don't control.
    DartdocOptionArgOnly<List<String>>(
        'allowWarningsInPackages', null, resourceProvider,
        help:
            'Package names to display warnings for (ignore all others if set).'),
    DartdocOptionArgOnly<List<String>>(
        'allowErrorsInPackages', null, resourceProvider,
        help: 'Package names to display errors for (ignore all others if set)'),
    DartdocOptionArgOnly<List<String>>(
        'ignoreWarningsInPackages', null, resourceProvider,
        help: 'Package names to ignore warnings for.  Takes priority over '
            'allow-warnings-in-packages'),
    DartdocOptionArgOnly<List<String>>(
        'ignoreErrorsInPackages', null, resourceProvider,
        help: 'Package names to ignore errors for. Takes priority over '
            'allow-errors-in-packages'),
    // Options for globally enabling/disabling warnings and errors across
    // packages.  Loaded from dartdoc_options.yaml, but command line arguments
    // will override.
    DartdocOptionArgFile<List<String>>('errors', null, resourceProvider,
        help: 'Additional warning names to force as errors.  Specify an empty '
                'list to force defaults (overriding dartdoc_options.yaml)\nDefaults:\n' +
            (packageWarningDefinitions.values
                    .where(
                        (d) => d.defaultWarningMode == PackageWarningMode.error)
                    .toList()
                      ..sort())
                .map((d) => '   ${d.warningName}: ${d.shortHelp}')
                .join('\n')),
    DartdocOptionArgFile<List<String>>('ignore', null, resourceProvider,
        help: 'Additional warning names to ignore.  Specify an empty list to '
                'force defaults (overriding dartdoc_options.yaml).\nDefaults:\n' +
            (packageWarningDefinitions.values
                    .where((d) =>
                        d.defaultWarningMode == PackageWarningMode.ignore)
                    .toList()
                      ..sort())
                .map((d) => '   ${d.warningName}: ${d.shortHelp}')
                .join('\n')),
    DartdocOptionArgFile<List<String>>('warnings', null, resourceProvider,
        help:
            'Additional warning names to show as warnings (instead of error or '
                    'ignore, if not warning by default).\nDefaults:\n' +
                (packageWarningDefinitions.values
                        .where((d) =>
                            d.defaultWarningMode == PackageWarningMode.warn)
                        .toList()
                          ..sort())
                    .map((d) => '   ${d.warningName}: ${d.shortHelp}')
                    .join('\n')),
    // Synthetic option uses a factory to build a PackageWarningOptions from all the above flags.
    DartdocOptionSyntheticOnly<PackageWarningOptions>(
      'packageWarningOptions',
      (DartdocSyntheticOption<PackageWarningOptions> option, Folder dir) =>
          PackageWarningOptions.fromOptions(option, dir, packageMetaProvider),
      resourceProvider,
    ),
  ];
}

class PackageWarningDefinition implements Comparable<PackageWarningDefinition> {
  final String warningName;
  final String shortHelp;
  final List<String> longHelp;
  final PackageWarning kind;
  final PackageWarningMode defaultWarningMode;

  const PackageWarningDefinition(this.kind, this.warningName, this.shortHelp,
      {List<String> longHelp, PackageWarningMode defaultWarningMode})
      : longHelp = longHelp ?? const [],
        defaultWarningMode = defaultWarningMode ?? PackageWarningMode.warn;

  @override
  int compareTo(PackageWarningDefinition other) {
    return warningName.compareTo(other.warningName);
  }
}

/// Same as [packageWarningDefinitions], except keyed by the warning name.
final Map<String, PackageWarningDefinition> packageWarningsByName =
    Map.fromEntries(packageWarningDefinitions.values
        .map((definition) => MapEntry(definition.warningName, definition)));

/// Provides description text and command line flags for warnings.
/// TODO(jcollins-g): Actually use this for command line flags.
final Map<PackageWarning, PackageWarningDefinition> packageWarningDefinitions =
    const {
  PackageWarning.ambiguousDocReference: PackageWarningDefinition(
      PackageWarning.ambiguousDocReference,
      'ambiguous-doc-reference',
      'A comment reference could refer to two or more different objects'),
  PackageWarning.ambiguousReexport: PackageWarningDefinition(
      PackageWarning.ambiguousReexport,
      'ambiguous-reexport',
      'A symbol is exported from private to public in more than one library and dartdoc can not determine which one is canonical',
      longHelp: [
        "Use {@canonicalFor @@name@@} in the desired library's documentation to resolve",
        "the ambiguity and/or override dartdoc's decision, or structure your package ",
        'so the reexport is less ambiguous.  The symbol will still be referenced in ',
        'all candidates -- this only controls the location where it will be written ',
        'and which library will be displayed in navigation for the relevant pages.',
        'The flag --ambiguous-reexport-scorer-min-confidence allows you to set the',
        'threshold at which this warning will appear.'
      ]),
  PackageWarning.ignoredCanonicalFor: PackageWarningDefinition(
      PackageWarning.ignoredCanonicalFor,
      'ignored-canonical-for',
      'A @canonicalFor tag refers to a library which this symbol can not be '
          'canonical for'),
  PackageWarning.noCanonicalFound: PackageWarningDefinition(
      PackageWarning.noCanonicalFound,
      'no-canonical-found',
      'A symbol is part of the public interface for this package, but no '
          'library documented with this package documents it so dartdoc can '
          'not link to it'),
  PackageWarning.noDefiningLibraryFound: PackageWarningDefinition(
      PackageWarning.noDefiningLibraryFound,
      'no-defining-library-found',
      'The defining library for an element could not be found; the library may '
          'be imported or exported with a non-standard URI',
      defaultWarningMode: PackageWarningMode.error),
  PackageWarning.notImplemented: PackageWarningDefinition(
      PackageWarning.notImplemented,
      'not-implemented',
      'The code makes use of a feature that is not yet implemented in dartdoc'),
  PackageWarning.noDocumentableLibrariesInPackage: PackageWarningDefinition(
    PackageWarning.noDocumentableLibrariesInPackage,
    'no-documentable-libraries',
    'The package is to be documented but has no Dart libraries to document',
    longHelp: [
      'Dartdoc could not find any public libraries to document in @@name@@, ',
      'but documentation was requested.  This might be expected for an ',
      'asset only package, in which case, disable this warning in your ',
      'dartdoc_options.yaml file.',
    ],
  ),
  PackageWarning.noLibraryLevelDocs: PackageWarningDefinition(
      PackageWarning.noLibraryLevelDocs,
      'no-library-level-docs',
      'There are no library level docs for this library'),
  PackageWarning.packageOrderGivesMissingPackageName: PackageWarningDefinition(
      PackageWarning.packageOrderGivesMissingPackageName,
      'category-order-gives-missing-package-name',
      'The category-order flag on the command line was given the name of a nonexistent package'),
  PackageWarning.reexportedPrivateApiAcrossPackages: PackageWarningDefinition(
      PackageWarning.reexportedPrivateApiAcrossPackages,
      'reexported-private-api-across-packages',
      'One or more libraries reexports private API members from outside its own package'),
  PackageWarning.unresolvedDocReference: PackageWarningDefinition(
      PackageWarning.unresolvedDocReference,
      'unresolved-doc-reference',
      'A comment reference could not be found in parameters, enclosing class, enclosing library, or at the top level of any documented library with the package'),
  PackageWarning.brokenLink: PackageWarningDefinition(PackageWarning.brokenLink,
      'broken-link', 'Dartdoc generated a link to a non-existent file'),
  PackageWarning.unknownDirective: PackageWarningDefinition(
      PackageWarning.unknownDirective,
      'unknown-directive',
      'A comment contains an unknown directive'),
  PackageWarning.unknownMacro: PackageWarningDefinition(
      PackageWarning.unknownMacro,
      'unknown-macro',
      'A comment reference contains an unknown macro'),
  PackageWarning.orphanedFile: PackageWarningDefinition(
      PackageWarning.orphanedFile,
      'orphaned-file',
      'Dartdoc generated files that are unreachable from the index'),
  PackageWarning.unknownFile: PackageWarningDefinition(
      PackageWarning.unknownFile,
      'unknown-file',
      'A leftover file exists in the tree that dartdoc did not write in this pass'),
  PackageWarning.missingFromSearchIndex: PackageWarningDefinition(
      PackageWarning.missingFromSearchIndex,
      'missing-from-search-index',
      'A file generated by dartdoc is not present in the generated index.json'),
  PackageWarning.typeAsHtml: PackageWarningDefinition(
      PackageWarning.typeAsHtml,
      'type-as-html',
      'Use of <> in a comment for type parameters is being treated as HTML by markdown',
      defaultWarningMode: PackageWarningMode.ignore),
  PackageWarning.invalidParameter: PackageWarningDefinition(
      PackageWarning.invalidParameter,
      'invalid-parameter',
      'A parameter given to a dartdoc directive was invalid.',
      defaultWarningMode: PackageWarningMode.error),
  PackageWarning.toolError: PackageWarningDefinition(PackageWarning.toolError,
      'tool-error', 'Unable to execute external tool.',
      defaultWarningMode: PackageWarningMode.error),
  PackageWarning.deprecated: PackageWarningDefinition(PackageWarning.deprecated,
      'deprecated', 'A dartdoc directive has a deprecated format.'),
  PackageWarning.unresolvedExport: PackageWarningDefinition(
      PackageWarning.unresolvedExport,
      'unresolved-export',
      'An export refers to a URI that cannot be resolved.',
      defaultWarningMode: PackageWarningMode.error),
  PackageWarning.duplicateFile: PackageWarningDefinition(
      PackageWarning.duplicateFile,
      'duplicate-file',
      'Dartdoc is trying to write to a duplicate filename based on the names of Dart symbols.',
      longHelp: [
        'Dartdoc generates a path and filename to write to for each symbol.',
        '@@name@@ conflicts with another symbol in the generated path, and',
        'therefore can not be written out.  Changing the name, library name, or',
        'class name (if appropriate) of one of the conflicting items can resolve',
        "the conflict.   Alternatively, use the @nodoc tag in one symbol's",
        'documentation comments to hide it.'
      ],
      defaultWarningMode: PackageWarningMode.error),
  PackageWarning.missingConstantConstructor: PackageWarningDefinition(
      PackageWarning.missingConstantConstructor,
      'missing-constant-constructor',
      'Dartdoc can not show the value of a constant because its constructor could not be resolved.',
      longHelp: [
        'To resolve a constant into its literal value, Dartdoc relies on the',
        "analyzer to resolve the constructor.  The analyzer didn't provide",
        'the constructor for @@name@@, which is usually due to an error in the',
        'code.  Use the analyzer to find missing imports.',
      ],
      // Defaults to ignore as this doesn't impact the docs severely but is
      // useful for debugging package structure.
      defaultWarningMode: PackageWarningMode.ignore),
};

/// Something that package warnings can be called on.  Optionally associated
/// with an analyzer [element].
abstract class Warnable implements Canonicalization {
  void warn(PackageWarning warning,
      {String message, Iterable<Locatable> referredFrom});

  Element get element;

  Warnable get enclosingElement;

  Package get package;
}

// The kinds of warnings that can be displayed when documenting a package.
enum PackageWarning {
  ambiguousDocReference,
  ambiguousReexport,
  ignoredCanonicalFor,
  noCanonicalFound,
  noDefiningLibraryFound,
  notImplemented,
  noDocumentableLibrariesInPackage,
  noLibraryLevelDocs,
  packageOrderGivesMissingPackageName,
  reexportedPrivateApiAcrossPackages,
  unresolvedDocReference,
  unknownDirective,
  unknownMacro,
  unknownHtmlFragment,
  brokenLink,
  duplicateFile,
  orphanedFile,
  unknownFile,
  missingFromSearchIndex,
  typeAsHtml,
  invalidParameter,
  toolError,
  deprecated,
  unresolvedExport,
  missingConstantConstructor,
  missingExampleFile,
}

/// Used to declare defaults for a particular package warning.
enum PackageWarningMode {
  ignore,
  warn,
  error,
}

/// Warnings it is OK to skip if we can determine the warnable isn't documented.
/// In particular, this set should not include warnings around public/private
/// or canonicalization problems, because those can break the isDocumented()
/// check.
final Set<PackageWarning> skipWarningIfNotDocumentedFor = {
  PackageWarning.unresolvedDocReference,
  PackageWarning.typeAsHtml
};

class PackageWarningOptions {
  final Map<PackageWarning, PackageWarningMode> warningModes = {};

  PackageWarningOptions() {
    for (var definition in packageWarningDefinitions.values) {
      switch (definition.defaultWarningMode) {
        case PackageWarningMode.warn:
          {
            warn(definition.kind);
          }
          break;
        case PackageWarningMode.error:
          {
            error(definition.kind);
          }
          break;
        case PackageWarningMode.ignore:
          {
            ignore(definition.kind);
          }
          break;
      }
    }
  }

  static PackageWarningOptions fromOptions(
    DartdocSyntheticOption<PackageWarningOptions> option,
    Folder dir,
    PackageMetaProvider packageMetaProvider,
  ) {
    // First, initialize defaults.
    var newOptions = PackageWarningOptions();
    var packageMeta = packageMetaProvider.fromDir(dir);

    // Interpret errors/warnings/ignore options.  In the event of conflict, warning overrides error and
    // ignore overrides warning.
    for (String warningName in option.parent['errors'].valueAt(dir) ?? []) {
      if (packageWarningsByName[warningName] != null) {
        newOptions.error(packageWarningsByName[warningName].kind);
      }
    }
    for (String warningName in option.parent['warnings'].valueAt(dir) ?? []) {
      if (packageWarningsByName[warningName] != null) {
        newOptions.warn(packageWarningsByName[warningName].kind);
      }
    }
    for (String warningName in option.parent['ignore'].valueAt(dir) ?? []) {
      if (packageWarningsByName[warningName] != null) {
        newOptions.ignore(packageWarningsByName[warningName].kind);
      }
    }

    // Check whether warnings are allowed at all in this package.
    List<String> allowWarningsInPackages =
        option.parent['allowWarningsInPackages'].valueAt(dir);
    List<String> allowErrorsInPackages =
        option.parent['allowErrorsInPackages'].valueAt(dir);
    List<String> ignoreWarningsInPackages =
        option.parent['ignoreWarningsInPackages'].valueAt(dir);
    List<String> ignoreErrorsInPackages =
        option.parent['ignoreErrorsInPackages'].valueAt(dir);
    if (allowWarningsInPackages != null &&
        !allowWarningsInPackages.contains(packageMeta.name)) {
      PackageWarning.values
          .forEach((PackageWarning kind) => newOptions.ignore(kind));
    }
    if (allowErrorsInPackages != null &&
        !allowWarningsInPackages.contains(packageMeta.name)) {
      PackageWarning.values
          .forEach((PackageWarning kind) => newOptions.ignore(kind));
    }
    if (ignoreWarningsInPackages != null &&
        ignoreWarningsInPackages.contains(packageMeta.name)) {
      PackageWarning.values
          .forEach((PackageWarning kind) => newOptions.ignore(kind));
    }
    if (ignoreErrorsInPackages != null &&
        ignoreErrorsInPackages.contains(packageMeta.name)) {
      PackageWarning.values
          .forEach((PackageWarning kind) => newOptions.ignore(kind));
    }
    return newOptions;
  }

  void ignore(PackageWarning kind) =>
      warningModes[kind] = PackageWarningMode.ignore;

  void warn(PackageWarning kind) =>
      warningModes[kind] = PackageWarningMode.warn;

  void error(PackageWarning kind) =>
      warningModes[kind] = PackageWarningMode.error;

  PackageWarningMode getMode(PackageWarning kind) => warningModes[kind];
}

class PackageWarningCounter {
  final Map<Element, Set<Tuple2<PackageWarning, String>>> countedWarnings = {};
  final _items = <Jsonable>[];
  final _displayedWarningCounts = <PackageWarning, int>{};
  final PackageGraph packageGraph;

  PackageWarningCounter(this.packageGraph);

  /// Actually write out the warning.  Assumes it is already counted with add.
  void _writeWarning(PackageWarning kind, PackageWarningMode mode,
      bool verboseWarnings, String name, String fullMessage) {
    if (mode == PackageWarningMode.ignore) {
      return;
    }
    String type;
    if (mode == PackageWarningMode.error) {
      type = 'error';
    } else if (mode == PackageWarningMode.warn) {
      type = 'warning';
    }
    if (type != null) {
      var entry = '  $type: $fullMessage';
      _displayedWarningCounts.putIfAbsent(kind, () => 0);
      _displayedWarningCounts[kind] += 1;
      if (_displayedWarningCounts[kind] == 1 &&
          verboseWarnings &&
          packageWarningDefinitions[kind].longHelp.isNotEmpty) {
        // First time we've seen this warning.  Give a little extra info.
        final separator = '\n            ';
        final nameSub = r'@@name@@';
        var verboseOut =
            '$separator${packageWarningDefinitions[kind].longHelp.join(separator)}'
                .replaceAll(nameSub, name);
        entry = '$entry$verboseOut';
      }
      assert(entry == entry.trimRight());
      _items.add(_JsonWarning(type, kind, fullMessage, entry));
    }
    for (var item in _items) {
      logWarning(item);
    }
    _items.clear();
  }

  /// Returns true if we've already warned for this.
  bool hasWarning(Warnable element, PackageWarning kind, String message) {
    var warningData = Tuple2<PackageWarning, String>(kind, message);
    if (countedWarnings.containsKey(element?.element)) {
      return countedWarnings[element?.element].contains(warningData);
    }
    return false;
  }

  /// Adds the warning to the counter, and writes out the fullMessage string
  /// if configured to do so.
  void addWarning(Warnable element, PackageWarning kind, String message,
      String fullMessage) {
    assert(!hasWarning(element, kind, message));
    // TODO(jcollins-g): Make addWarning not accept nulls for element.
    PackageWarningOptionContext config =
        element?.config ?? packageGraph.defaultPackage.config;
    var warningMode = config.packageWarningOptions.getMode(kind);
    if (!config.allowNonLocalWarnings && !(element?.package?.isLocal ?? true)) {
      warningMode = PackageWarningMode.ignore;
    }
    if (warningMode == PackageWarningMode.warn) {
      warningCount += 1;
    } else if (warningMode == PackageWarningMode.error) {
      errorCount += 1;
    }
    var warningData = Tuple2<PackageWarning, String>(kind, message);
    countedWarnings.putIfAbsent(element?.element, () => {}).add(warningData);
    _writeWarning(kind, warningMode, config.verboseWarnings,
        element?.fullyQualifiedName, fullMessage);
  }

  int errorCount = 0;
  int warningCount = 0;

  @override
  String toString() {
    var errors = '$errorCount ${errorCount == 1 ? "error" : "errors"}';
    var warnings =
        '$warningCount ${warningCount == 1 ? "warning" : "warnings"}';
    return [errors, warnings].join(', ');
  }
}

class _JsonWarning extends Jsonable {
  final String type;
  final PackageWarning kind;
  final String message;

  @override
  final String text;

  _JsonWarning(this.type, this.kind, this.message, this.text);

  @override
  Map<String, dynamic> toJson() => {
        'type': type,
        'kind': packageWarningDefinitions[kind].warningName,
        'message': message,
        'text': text
      };
}
