// Copyright (c) 2019, 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 'dart:convert';

import 'package:collection/collection.dart';
import 'package:dartdoc/src/model/directives/categorization.dart';
import 'package:dartdoc/src/model/documentable.dart';
import 'package:dartdoc/src/model/inheritable.dart';
import 'package:dartdoc/src/model/library.dart';
import 'package:dartdoc/src/model/model_element.dart';
import 'package:dartdoc/src/model/nameable.dart';

String generateCategoryJson(Iterable<Categorization> categories, bool pretty) {
  final indexItems = [
    for (final categorization
        in categories.sorted(_compareElementRepresentations))
      <String, Object?>{
        'name': categorization.name,
        'qualifiedName': categorization.canonicalQualifiedName,
        'href': categorization.href,
        // TODO(srawlins): Rename to 'kind'.
        'type': categorization.kind.toString(),
        if (categorization.hasCategoryNames)
          'categories': categorization.categoryNames,
        if (categorization.hasSubCategoryNames)
          'subcategories': categorization.subCategoryNames,
      }
  ];

  final encoder =
      pretty ? const JsonEncoder.withIndent(' ') : const JsonEncoder();

  return encoder.convert(indexItems.toList(growable: false));
}

/// Generates the text of the search index file (`index.json`) containing
/// [indexedElements] and [packageOrder].
///
/// Passing `pretty: true` will use a [JsonEncoder] with a single-space indent.
String generateSearchIndexJson(Iterable<Documentable> indexedElements,
    {required List<String> packageOrder, required bool pretty}) {
  var indexItems = <Map<String, Object?>>[];

  for (var element in indexedElements.sorted(_compareElementRepresentations)) {
    assert(
      element.href != null,
      "element expected to have a non-null 'href', but was null: "
      "'$element'",
    );
    var item = {
      'name': element.name,
      'qualifiedName': element.canonicalQualifiedName,
      'href': element.href,
      'kind': element.kind.index,
      if (element is Inheritable) 'overriddenDepth': element.overriddenDepth,
    };

    if (element is ModelElement) {
      item['packageRank'] = _packageRank(packageOrder, element);
      item['desc'] = _removeHtmlTags(element.oneLineDoc);
      var enclosingElement = element.enclosingElement is Library
          ? element.canonicalLibrary
          : element.enclosingElement;
      if (enclosingElement != null) {
        assert(
          enclosingElement.href != null,
          "'enclosedBy' element expected to have a non-null 'href', "
          "but was null: '$element', enclosed by the "
          "${enclosingElement.runtimeType} '$enclosingElement'",
        );
        item['enclosedBy'] = {
          'name': enclosingElement.name,
          'kind': enclosingElement.kind.index,
          'href': enclosingElement.href,
        };
      }
    }
    indexItems.add(item);
  }

  final encoder =
      pretty ? const JsonEncoder.withIndent(' ') : const JsonEncoder();

  return encoder.convert(indexItems);
}

/// The "package rank" of [element], given a [packageOrder].
///
/// Briefly, this is 10 times the element's package's position in the
/// [packageOrder], or 10 times the length of [packageOrder] if the element's
/// package is not listed in [packageOrder].
int _packageRank(List<String> packageOrder, ModelElement element) {
  if (packageOrder.isEmpty) return 0;
  var packageName = element.package.name;
  var index = packageOrder.indexOf(packageName);
  if (index == -1) return packageOrder.length * 10;
  if (packageName == 'Dart' &&
      !_dartCoreLibraries.contains(element.library.name)) {
    // Non-"core" Dart SDK libraries should be ranked slightly lower than "core"
    // Dart SDK libraries. The "core" Dart SDK libraries are the ones labeled as
    // such at <https://api.dart.dev>, which can be used in both VM and Web
    // environments.
    // Note we choose integers throughout this function (as opposed to adding
    // 0.5 here) in order to facilitate a proper [Comparable] comparison.
    return index * 10 + 5;
  }
  return index * 10;
}

/// The set of "core" Dart libraries, used to rank contained items above items
/// declared elsewhere in the Dart SDK.
const _dartCoreLibraries = {
  'dart:async',
  'dart:collection',
  'dart:convert',
  'dart:core',
  'dart:developer',
  'dart:math',
  'dart:typed_data',

  // Plus the two core Flutter engine libraries.
  'dart:ui',
  'dart:web_ui',
};

String _removeHtmlTags(String? input) =>
    input?.replaceAll(_htmlTagPattern, '') ?? '';

final _htmlTagPattern =
    RegExp(r'<[^>]*>', multiLine: true, caseSensitive: true);

// Compares two elements, first by fully qualified name, then by kind.
int _compareElementRepresentations(Documentable a, Documentable b) {
  final value =
      compareNatural(a.canonicalQualifiedName, b.canonicalQualifiedName);
  if (value == 0) {
    return compareNatural(a.kind.toString(), b.kind.toString());
  }
  return value;
}

extension on Nameable {
  /// The fully qualified name of this element, but using the canonical library,
  /// if it has one.
  String get canonicalQualifiedName {
    var self = this;
    if (self is Library) return name;
    if (self is ModelElement) {
      var library = self.canonicalLibrary ?? self.library;
      return '${library.name}.${self.qualifiedName}';
    }
    return name;
  }
}
