// 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:dartdoc/src/generator/generator.dart';
import 'package:dartdoc/src/generator/generator_backend.dart';
import 'package:dartdoc/src/generator/templates.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/model_utils.dart';
import 'package:dartdoc/src/runtime_stats.dart';
import 'package:dartdoc/src/warnings.dart';

/// A [Generator] that delegates rendering to a [GeneratorBackend] and delegates
/// file creation to a [FileWriter].
class GeneratorFrontEnd implements Generator {
  final GeneratorBackend _generatorBackend;

  GeneratorFrontEnd(this._generatorBackend);

  @override
  Future<void> generate(PackageGraph? packageGraph) async {
    if (_generatorBackend.templates is RuntimeTemplates) {
      packageGraph?.defaultPackage.warn(
        PackageWarning.deprecated,
        message: "The '--templates-dir' option is deprecated, and will soon no "
            'longer be supported.',
      );
    }

    await _generatorBackend.generateAdditionalFiles();

    if (packageGraph == null) {
      return;
    }

    var indexElements = _generateDocs(packageGraph);
    var categories = indexElements
        .whereType<Categorization>()
        .where((e) => e.hasCategorization)
        .toList(growable: false);
    _generatorBackend.generateCategoryJson(categories);
    _generatorBackend.generateSearchIndex(indexElements);
  }

  @override
  Set<String> get writtenFiles => _generatorBackend.writer.writtenFiles;

  /// Traverses the [packageGraph] and generates documentation for all contained
  /// elements.
  List<Documentable> _generateDocs(PackageGraph packageGraph) {
    runtimeStats.resetAccumulators({
      'writtenCategoryFileCount',
      'writtenClassFileCount',
      'writtenConstructorFileCount',
      'writtenEnumFileCount',
      'writtenExtensionFileCount',
      'writtenExtensionTypeFileCount',
      'writtenFunctionFileCount',
      'writtenLibraryFileCount',
      'writtenMethodFileCount',
      'writtenMixinFileCount',
      'writtenPackageFileCount',
      'writtenPropertyFileCount',
      'writtenSidebarFileCount',
      'writtenTopLevelPropertyFileCount',
      'writtenTypedefFileCount'
    });
    _generatorBackend.generatePackage(
        packageGraph, packageGraph.defaultPackage);

    var indexAccumulator = <Documentable>[];
    var multiplePackages = packageGraph.localPackages.length > 1;

    void generateConstants(Container container, Library library) {
      for (var constant in container.constantFields.whereDocumented) {
        if (!constant.isCanonical) continue;
        indexAccumulator.add(constant);
        _generatorBackend.generateProperty(
            packageGraph, library, container, constant);
      }
    }

    void generateConstructors(Constructable constructable, Library library) {
      for (var constructor in constructable.constructors.whereDocumented) {
        if (!constructor.isCanonical) continue;
        indexAccumulator.add(constructor);
        _generatorBackend.generateConstructor(
            packageGraph, library, constructable, constructor);
      }
    }

    void generateInstanceMethods(Container container, Library library) {
      for (var method in container.instanceMethods.whereDocumented) {
        if (!method.isCanonical) continue;
        indexAccumulator.add(method);
        _generatorBackend.generateMethod(
            packageGraph, library, container, method);
      }
    }

    void generateInstanceOperators(Container container, Library library) {
      for (var operator in container.instanceOperators.whereDocumented) {
        if (!operator.isCanonical) continue;
        indexAccumulator.add(operator);
        _generatorBackend.generateMethod(
            packageGraph, library, container, operator);
      }
    }

    void generateInstanceProperties(Container container, Library library) {
      for (var property in container.instanceFields.whereDocumented) {
        if (!property.isCanonical) continue;
        indexAccumulator.add(property);
        _generatorBackend.generateProperty(
            packageGraph, library, container, property);
      }
    }

    void generateStaticMethods(Container container, Library library) {
      for (var method in container.staticMethods.whereDocumented) {
        if (!method.isCanonical) continue;
        indexAccumulator.add(method);
        _generatorBackend.generateMethod(
            packageGraph, library, container, method);
      }
    }

    void generateStaticProperties(Container container, Library library) {
      for (var property in container.variableStaticFields.whereDocumented) {
        if (!property.isCanonical) continue;
        indexAccumulator.add(property);
        _generatorBackend.generateProperty(
            packageGraph, library, container, property);
      }
    }

    for (var package in packageGraph.localPackages) {
      if (multiplePackages) {
        logInfo('Generating docs for package ${package.name}...');
      }
      for (var category in package.categories.whereDocumented) {
        logInfo('Generating docs for category ${category.name} from '
            '${category.package.fullyQualifiedName}...');
        indexAccumulator.add(category);
        _generatorBackend.generateCategory(packageGraph, category);
      }

      for (var lib in package.libraries.whereDocumented) {
        if (!multiplePackages) {
          logInfo('Generating docs for library ${lib.breadcrumbName} from '
              '${lib.element2.firstFragment.source.uri}...');
        }
        if (!lib.isAnonymous && !lib.hasDocumentation) {
          packageGraph.warnOnElement(lib, PackageWarning.noLibraryLevelDocs);
        }
        indexAccumulator.add(lib);
        _generatorBackend.generateLibrary(packageGraph, lib);

        for (var class_ in lib.classesAndExceptions.whereDocumentedIn(lib)) {
          indexAccumulator.add(class_);
          _generatorBackend.generateClass(packageGraph, lib, class_);

          var canonicalLibrary = class_.canonicalLibraryOrThrow;
          generateConstants(class_, canonicalLibrary);
          generateConstructors(class_, canonicalLibrary);
          generateInstanceMethods(class_, canonicalLibrary);
          generateInstanceOperators(class_, canonicalLibrary);
          generateInstanceProperties(class_, canonicalLibrary);
          generateStaticMethods(class_, canonicalLibrary);
          generateStaticProperties(class_, canonicalLibrary);
        }

        for (var extension in lib.extensions.whereDocumentedIn(lib)) {
          indexAccumulator.add(extension);
          _generatorBackend.generateExtension(packageGraph, lib, extension);

          var canonicalLibrary = extension.canonicalLibraryOrThrow;
          generateConstants(extension, canonicalLibrary);
          generateInstanceMethods(extension, canonicalLibrary);
          generateInstanceOperators(extension, canonicalLibrary);
          generateInstanceProperties(extension, canonicalLibrary);
          generateStaticMethods(extension, canonicalLibrary);
          generateStaticProperties(extension, canonicalLibrary);
        }

        for (var extensionType in lib.extensionTypes.whereDocumentedIn(lib)) {
          indexAccumulator.add(extensionType);
          _generatorBackend.generateExtensionType(
              packageGraph, lib, extensionType);

          var canonicalLibrary = extensionType.canonicalLibraryOrThrow;
          generateConstants(extensionType, canonicalLibrary);
          generateConstructors(extensionType, canonicalLibrary);
          generateInstanceMethods(extensionType, canonicalLibrary);
          generateInstanceOperators(extensionType, canonicalLibrary);
          generateInstanceProperties(extensionType, canonicalLibrary);
          generateStaticMethods(extensionType, canonicalLibrary);
          generateStaticProperties(extensionType, canonicalLibrary);
        }

        for (var mixin in lib.mixins.whereDocumentedIn(lib)) {
          indexAccumulator.add(mixin);
          _generatorBackend.generateMixin(packageGraph, lib, mixin);

          var canonicalLibrary = mixin.canonicalLibraryOrThrow;
          generateConstants(mixin, canonicalLibrary);
          generateInstanceMethods(mixin, canonicalLibrary);
          generateInstanceOperators(mixin, canonicalLibrary);
          generateInstanceProperties(mixin, canonicalLibrary);
          generateStaticMethods(mixin, canonicalLibrary);
          generateStaticProperties(mixin, canonicalLibrary);
        }

        for (var enum_ in lib.enums.whereDocumentedIn(lib)) {
          indexAccumulator.add(enum_);
          _generatorBackend.generateEnum(packageGraph, lib, enum_);

          var canonicalLibrary = enum_.canonicalLibraryOrThrow;
          generateConstants(enum_, canonicalLibrary);
          generateConstructors(enum_, canonicalLibrary);
          generateInstanceMethods(enum_, canonicalLibrary);
          generateInstanceOperators(enum_, canonicalLibrary);
          generateInstanceProperties(enum_, canonicalLibrary);
          generateStaticMethods(enum_, canonicalLibrary);
          generateStaticProperties(enum_, canonicalLibrary);
        }

        for (var constant in lib.constants.whereDocumentedIn(lib)) {
          indexAccumulator.add(constant);
          _generatorBackend.generateTopLevelProperty(
              packageGraph, lib, constant);
        }

        for (var property in lib.properties.whereDocumentedIn(lib)) {
          indexAccumulator.add(property);
          _generatorBackend.generateTopLevelProperty(
              packageGraph, lib, property);
        }

        for (var function in lib.functions.whereDocumentedIn(lib)) {
          indexAccumulator.add(function);
          _generatorBackend.generateFunction(packageGraph, lib, function);
        }

        for (var typeDef in lib.typedefs.whereDocumentedIn(lib)) {
          indexAccumulator.add(typeDef);
          _generatorBackend.generateTypeDef(packageGraph, lib, typeDef);
        }
      }
    }
    return indexAccumulator;
  }
}
