// 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/file_system/file_system.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/generator/generator.dart';
import 'package:dartdoc/src/generator/generator_utils.dart' as generator_util;
import 'package:dartdoc/src/generator/template_data.dart';
import 'package:dartdoc/src/generator/templates.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/runtime_stats.dart';
import 'package:dartdoc/src/version.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:path/path.dart' as p show Context;

/// Configuration options for Dartdoc's default backend.
class DartdocGeneratorBackendOptions implements TemplateOptions {
  @override
  final String? relCanonicalPrefix;

  @override
  final String toolVersion;

  final String? favicon;

  final bool prettyIndexJson;

  @override
  final bool useBaseHref;

  @override
  final String customHeaderContent;

  @override
  final String customFooterContent;

  @override
  final String customInnerFooterText;

  final String? resourcesDir;

  final List<String> packageOrder;

  DartdocGeneratorBackendOptions.fromContext(
      DartdocGeneratorOptionContext context)
      : relCanonicalPrefix = context.relCanonicalPrefix,
        toolVersion = packageVersion,
        favicon = context.favicon,
        prettyIndexJson = context.prettyIndexJson,
        useBaseHref = context.useBaseHref,
        customHeaderContent = context.header,
        customFooterContent = context.footer,
        customInnerFooterText = context.footerText,
        resourcesDir = context.resourcesDir,
        packageOrder = context.packageOrder;
}

/// Outputs generated documentation.
abstract class GeneratorBackend {
  final DartdocGeneratorBackendOptions options;
  final Templates templates;

  final FileWriter writer;
  final ResourceProvider resourceProvider;
  final p.Context _pathContext;

  GeneratorBackend(
      this.options, this.templates, this.writer, this.resourceProvider)
      : _pathContext = resourceProvider.pathContext;

  /// Binds template data and emits the content to the [writer].
  void write(
    FileWriter writer,
    String filename,
    TemplateData data,
    String content, {
    bool isSidebar = false,
  }) {
    if (!options.useBaseHref) {
      content = content.replaceAll(
        htmlBasePlaceholder,
        // URLs in sidebars are tweaked in the front-end; other URLs use
        // `htmlBase`.
        isSidebar ? '' : data.htmlBase,
      );
    }
    var e = data.self;
    writer.write(filename, content, element: e is Warnable ? e : null);
  }

  /// Emits JSON describing the [categories] defined by the package.
  void generateCategoryJson(List<Categorization> categories) {
    var json = '[]';
    if (categories.isNotEmpty) {
      json = generator_util.generateCategoryJson(
          categories, options.prettyIndexJson);
      if (!options.useBaseHref) {
        json = json.replaceAll(htmlBasePlaceholder, '');
      }
    }

    writer.write(_pathContext.join('categories.json'), '$json\n');
  }

  /// Emits a JSON catalog of [indexedElements] for use with a search index.
  void generateSearchIndex(List<Documentable> indexedElements) {
    var json = generator_util.generateSearchIndexJson(
      indexedElements,
      packageOrder: options.packageOrder,
      pretty: options.prettyIndexJson,
    );
    if (!options.useBaseHref) {
      json = json.replaceAll(htmlBasePlaceholder, '');
    }
    writer.write(_pathContext.join('index.json'), '$json\n');
  }

  /// Emits documentation content for the [category].
  void generateCategory(PackageGraph packageGraph, Category category) {
    var data = CategoryTemplateData(options, packageGraph, category);
    var content = templates.renderCategory(data);
    write(writer, category.filePath, data, content);
    if (category.filePath != category.redirectFilePath) {
      var redirectContent = templates.renderCategoryRedirect(data);
      write(writer, category.redirectFilePath, data, redirectContent);
    }

    runtimeStats.incrementAccumulator('writtenCategoryFileCount');
  }

  /// Emits documentation content for the [class_].
  void generateClass(PackageGraph packageGraph, Library library, Class class_) {
    var data = ClassTemplateData(options, packageGraph, library, class_);
    var content = templates.renderClass(data);
    write(writer, class_.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenClassFileCount');
  }

  /// Emits documentation content for the [constructor].
  void generateConstructor(PackageGraph packageGraph, Library library,
      Constructable constructable, Constructor constructor) {
    var data = ConstructorTemplateData(
        options, packageGraph, library, constructable, constructor);
    var content = templates.renderConstructor(data);
    write(writer, constructor.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenConstructorFileCount');
  }

  /// Emits documentation content for the [enum_].
  void generateEnum(PackageGraph packageGraph, Library library, Enum enum_) {
    var data = EnumTemplateData(options, packageGraph, library, enum_);
    var content = templates.renderEnum(data);
    write(writer, enum_.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenEnumFileCount');
  }

  /// Emits documentation content for the [extension].
  void generateExtension(
      PackageGraph packageGraph, Library library, Extension extension) {
    var data = ExtensionTemplateData(options, packageGraph, library, extension);
    var content = templates.renderExtension(data);
    write(writer, extension.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenExtensionFileCount');
  }

  /// Emits documentation content for the [extensionType].
  void generateExtensionType(
      PackageGraph packageGraph, Library library, ExtensionType extensionType) {
    var data = ExtensionTypeTemplateData(
        options, packageGraph, library, extensionType);
    var content = templates.renderExtensionType(data);
    write(writer, extensionType.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenExtensionTypeFileCount');
  }

  /// Emits documentation content for the [function].
  void generateFunction(
      PackageGraph packageGraph, Library library, ModelFunction function) {
    var data = FunctionTemplateData(options, packageGraph, library, function);
    var content = templates.renderFunction(data);
    write(writer, function.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenFunctionFileCount');
  }

  /// Emits documentation content for the [library], and the content for the
  /// library's previous location (which just redirects to the new location).
  void generateLibrary(PackageGraph packageGraph, Library library) {
    var data = LibraryTemplateData(options, packageGraph, library);
    var content = templates.renderLibrary(data);
    var redirectContent = templates.renderLibraryRedirect(data);
    write(writer, library.filePath, data, content);
    write(writer, library.redirectingPath, data, redirectContent);
    runtimeStats.incrementAccumulator('writtenLibraryFileCount');
  }

  /// Emits documentation content for the [method].
  void generateMethod(PackageGraph packageGraph, Library library,
      Container container, Method method) {
    var data =
        MethodTemplateData(options, packageGraph, library, container, method);
    var content = templates.renderMethod(data);
    write(writer, method.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenMethodFileCount');
  }

  /// Emits documentation content for the [mixin].
  void generateMixin(PackageGraph packageGraph, Library library, Mixin mixin) {
    var data = MixinTemplateData(options, packageGraph, library, mixin);
    var content = templates.renderMixin(data);
    write(writer, mixin.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenMixinFileCount');
  }

  /// Emits documentation content for the [package].
  void generatePackage(PackageGraph packageGraph, Package package) {
    var data = PackageTemplateData(options, packageGraph, package);
    var content = templates.renderIndex(data);
    write(writer, package.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenPackageFileCount');
  }

  /// Emits documentation content for the [field].
  void generateProperty(PackageGraph packageGraph, Library library,
      Container container, Field field) {
    var data =
        PropertyTemplateData(options, packageGraph, library, container, field);
    var content = templates.renderProperty(data);
    write(writer, field.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenPropertyFileCount');
  }

  /// Emits documentation content for the [property].
  void generateTopLevelProperty(
      PackageGraph packageGraph, Library library, TopLevelVariable property) {
    var data =
        TopLevelPropertyTemplateData(options, packageGraph, library, property);
    var content = templates.renderTopLevelProperty(data);
    write(writer, property.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenTopLevelPropertyFileCount');
  }

  /// Emits documentation content for the [typedef].
  void generateTypeDef(
      PackageGraph packageGraph, Library library, Typedef typedef) {
    var data = TypedefTemplateData(options, packageGraph, library, typedef);
    var content = templates.renderTypedef(data);
    write(writer, typedef.filePath, data, content);
    runtimeStats.incrementAccumulator('writtenTypedefFileCount');
  }

  /// Emits files not specific to a Dart language element (like a favicon, etc).
  Future<void> generateAdditionalFiles();
}
