// 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 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/model/comment_referable.dart';
import 'package:dartdoc/src/model/kind.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/warnings.dart';

/// A subcategory of a package, containing elements tagged with `{@category}`.
class Category
    with
        Nameable,
        Warnable,
        CommentReferable,
        Locatable,
        MarkdownFileDocumentation,
        LibraryContainer,
        TopLevelContainer
    implements Documentable {
  /// The package in which this category is contained.
  ///
  /// All libraries in [libraries] must come from [package].
  @override
  final Package package;

  final String? _name;

  @override
  final DartdocOptionContext config;

  final Set<Class> _classes = {};

  final Set<Class> _exceptions = {};

  @override
  final Set<TopLevelVariable> constants = {};

  @override
  final Set<Extension> extensions = {};

  @override
  final Set<ExtensionType> extensionTypes = {};

  @override
  final Set<Enum> enums = {};

  @override
  final Set<ModelFunction> functions = {};

  @override
  final Set<Mixin> mixins = {};

  @override
  final Set<TopLevelVariable> properties = {};

  @override
  final Set<Typedef> typedefs = {};

  final CategoryDefinition _categoryDefinition;

  Category(this._name, this.package, this.config)
      : _categoryDefinition =
            config.categories.categoryDefinitions[_name.orDefault] ??
                CategoryDefinition(_name, null, null);

  Iterable<ExternalItem> get externalItems => _categoryDefinition.externalItems;

  void addClass(Class class_) {
    if (class_.isErrorOrException) {
      _exceptions.add(class_);
    } else {
      _classes.add(class_);
    }
  }

  @override
  Element2? get element => null;

  @override
  String get name => _categoryDefinition.displayName;

  @override
  String get sortKey => _name.orDefault;

  @override
  List<String> get containerOrder => config.categoryOrder;

  @override
  String get enclosingName => package.name;

  @override
  PackageGraph get packageGraph => package.packageGraph;

  @override
  List<Locatable> get documentationFrom => [this];

  @override
  DocumentLocation get documentedWhere => package.documentedWhere;

  @override
  late final bool isDocumented =
      documentedWhere != DocumentLocation.missing && documentationFile != null;

  String get fileName {
    assert(_name != null);
    return '$_name-topic.html';
  }

  String get filePath => 'topics/$fileName';

  /// Prior to dartdoc 8.3.4 the `displayName` was used in the file path
  /// for category pages. We now create a redirect file here instead.
  String get redirectFilePath => 'topics/$name-topic.html';

  @override
  String? get href => isCanonical ? '${package.baseHref}$filePath' : null;

  @override
  String? get aboveSidebarPath => null;

  @override
  String? get belowSidebarPath => null;

  String get categoryLabel {
    final buffer = StringBuffer('<span class="category ');
    buffer.writeAll(name.toLowerCase().split(' '), '-');
    buffer.write(' cp-');
    buffer.write(categoryIndex);

    if (isDocumented) {
      buffer.write(' linked');
    }

    buffer.write('"'); // Wrap up the class list and begin title
    buffer.write(' title="This is part of the ');
    buffer.write(name);
    buffer.write(' ');
    buffer.write(kind);
    buffer.write('.">'); // Wrap up the title

    buffer.write(linkedName);
    buffer.write('</span>');

    return buffer.toString();
  }

  String get linkedName {
    final unbrokenName = name.replaceAll(' ', '&nbsp;');
    if (isDocumented) {
      final href = this.href;
      if (href == null) {
        throw StateError("Requesting the 'linkedName' of a non-canonical "
            "category: '$name'");
      }
      return '<a href="$href">$unbrokenName</a>';
    } else {
      return unbrokenName;
    }
  }

  /// The position in the container order for this category.
  int get categoryIndex => package.categories.indexOf(this);

  @override
  bool get isCanonical =>
      config.categories.categoryDefinitions.containsKey(sortKey);

  @override
  Kind get kind => Kind.topic;

  @override
  File? get documentationFile {
    var documentationMarkdown = _categoryDefinition.documentationMarkdown;
    if (documentationMarkdown != null) {
      return config.resourceProvider.getFile(documentationMarkdown);
    }
    return null;
  }

  @override
  Iterable<Class> get classes => _classes;

  @override
  Iterable<Class> get exceptions => _exceptions;

  @override
  Map<String, CommentReferable> get referenceChildren => const {};

  @override
  Iterable<CommentReferable> get referenceParents => const [];
}

extension on String? {
  String get orDefault => this ?? '<default>';
}

/// A external link for an item in a dartdoc category.
///
/// This is a name, url, and optional documentation text.
class ExternalItem {
  final String name;
  final String url;
  final String docs;

  ExternalItem({
    required this.name,
    required this.url,
    required String? docs,
  }) : docs = docs ?? '';

  @override
  String toString() => '$name $url';
}
