// Copyright (c) 2015, 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.

@Renderer(#renderCategory, Context<CategoryTemplateData>(), 'category',
    visibleTypes: _visibleTypes)
@Renderer(#renderClass, Context<ClassTemplateData>(), 'class')
@Renderer(#renderConstructor, Context<ConstructorTemplateData>(), 'constructor')
@Renderer(#renderEnum, Context<EnumTemplateData>(), 'enum')
@Renderer(#renderError, Context<PackageTemplateData>(), '404error')
@Renderer(#renderExtension, Context<ExtensionTemplateData>(), 'extension')
@Renderer(#renderFunction, Context<FunctionTemplateData>(), 'function')
@Renderer(#renderIndex, Context<PackageTemplateData>(), 'index')
@Renderer(#renderLibrary, Context<LibraryTemplateData>(), 'library')
@Renderer(#renderMethod, Context<MethodTemplateData>(), 'method')
@Renderer(#renderMixin, Context<MixinTemplateData>(), 'mixin')
@Renderer(#renderProperty, Context<PropertyTemplateData>(), 'property')
@Renderer(
    #renderSidebarForContainer,
    Context<TemplateDataWithContainer<Documentable>>(),
    '_sidebar_for_container')
@Renderer(#renderSidebarForLibrary,
    Context<TemplateDataWithLibrary<Documentable>>(), '_sidebar_for_library')
@Renderer(#renderTopLevelProperty, Context<TopLevelPropertyTemplateData>(),
    'top_level_property')
@Renderer(#renderTypedef, Context<TypedefTemplateData>(), 'typedef')
library dartdoc.templates;

import 'package:analyzer/file_system/file_system.dart';
import 'package:dartdoc/dartdoc.dart';
import 'package:dartdoc/options.dart';
import 'package:dartdoc/src/generator/resource_loader.dart';
import 'package:dartdoc/src/generator/template_data.dart';
import 'package:dartdoc/src/generator/templates.aot_renderers_for_html.dart'
    as aot_renderers_for_html;
import 'package:dartdoc/src/generator/templates.aot_renderers_for_md.dart'
    as aot_renderers_for_md;
import 'package:dartdoc/src/generator/templates.runtime_renderers.dart'
    as runtime_renderers;
import 'package:dartdoc/src/model/annotation.dart';
import 'package:dartdoc/src/model/feature_set.dart';
import 'package:dartdoc/src/model/language_feature.dart';
import 'package:dartdoc/src/mustachio/annotations.dart';
import 'package:dartdoc/src/mustachio/renderer_base.dart';
import 'package:meta/meta.dart';

const _visibleTypes = {
  Annotation,
  Callable,
  Category,
  Class,
  Constructor,
  DefinedElementType,
  Documentable,
  ElementType,
  Enum,
  Extension,
  FeatureSet,
  FunctionTypeElementType,
  LanguageFeature,
  Library,
  LibraryContainer,
  Method,
  ModelElement,
  Package,
  // For getters like `isNotEmpty`; perhaps a smell, but currently in use.
  String,
  TopLevelVariable,
  TypeParameter,
};

/// The collection of [Template] objects
abstract class Templates {
  String renderCategory(CategoryTemplateData context);
  String renderClass<T extends Class>(ClassTemplateData<T> context);
  String renderConstructor(ConstructorTemplateData context);
  String renderEnum(EnumTemplateData context);
  String renderError(PackageTemplateData context);
  String renderExtension(ExtensionTemplateData context);
  String renderFunction(FunctionTemplateData context);
  String renderIndex(PackageTemplateData context);
  String renderLibrary(LibraryTemplateData context);
  String renderMethod(MethodTemplateData context);
  String renderMixin(MixinTemplateData context);
  String renderProperty(PropertyTemplateData context);
  String renderSidebarForContainer(
      TemplateDataWithContainer<Documentable> context);
  String renderSidebarForLibrary(TemplateDataWithLibrary<Documentable> context);
  String renderTopLevelProperty(TopLevelPropertyTemplateData context);
  String renderTypedef(TypedefTemplateData context);

  /// Creates a [Templates] instance either from the default set of templates,
  /// or a custom set if the 'templatesDir' Dartdoc option is used.
  ///
  /// [forceRuntimeTemplates] should only be given [true] during tests.
  static Future<Templates> fromContext(DartdocGeneratorOptionContext context,
      {bool forceRuntimeTemplates = false}) async {
    var templatesDir = context.templatesDir;
    var format = context.format;

    if (templatesDir != null) {
      return RuntimeTemplates._create(
          context.resourceProvider.getFolder(templatesDir), format,
          resourceProvider: context.resourceProvider);
    } else if (forceRuntimeTemplates) {
      var directory = await context.resourceProvider
          .getResourceFolder('package:dartdoc/templates/$format');
      return RuntimeTemplates._create(directory, format,
          resourceProvider: context.resourceProvider);
    } else if (format == 'html') {
      return HtmlAotTemplates();
    } else if (format == 'md') {
      return MarkdownAotTemplates();
    } else {
      throw ArgumentError.value(format, 'format');
    }
  }
}

class HtmlAotTemplates implements Templates {
  @override
  String renderCategory(CategoryTemplateData context) =>
      aot_renderers_for_html.renderCategory(context);

  @override
  String renderClass<T extends Class>(ClassTemplateData<T> context) =>
      aot_renderers_for_html.renderClass(context);

  @override
  String renderConstructor(ConstructorTemplateData context) =>
      aot_renderers_for_html.renderConstructor(context);

  @override
  String renderEnum(EnumTemplateData context) =>
      aot_renderers_for_html.renderEnum(context);

  @override
  String renderError(PackageTemplateData context) =>
      aot_renderers_for_html.renderError(context);

  @override
  String renderExtension(ExtensionTemplateData context) =>
      aot_renderers_for_html.renderExtension(context);

  @override
  String renderFunction(FunctionTemplateData context) =>
      aot_renderers_for_html.renderFunction(context);

  @override
  String renderIndex(PackageTemplateData context) =>
      aot_renderers_for_html.renderIndex(context);

  @override
  String renderLibrary(LibraryTemplateData context) =>
      aot_renderers_for_html.renderLibrary(context);

  @override
  String renderMethod(MethodTemplateData context) =>
      aot_renderers_for_html.renderMethod(context);

  @override
  String renderMixin(MixinTemplateData context) =>
      aot_renderers_for_html.renderMixin(context);

  @override
  String renderProperty(PropertyTemplateData context) =>
      aot_renderers_for_html.renderProperty(context);

  @override
  String renderSidebarForContainer(
          TemplateDataWithContainer<Documentable> context) =>
      aot_renderers_for_html.renderSidebarForContainer(context);

  @override
  String renderSidebarForLibrary(
          TemplateDataWithLibrary<Documentable> context) =>
      aot_renderers_for_html.renderSidebarForLibrary(context);

  @override
  String renderTopLevelProperty(TopLevelPropertyTemplateData context) =>
      aot_renderers_for_html.renderTopLevelProperty(context);

  @override
  String renderTypedef(TypedefTemplateData context) =>
      aot_renderers_for_html.renderTypedef(context);
}

class MarkdownAotTemplates implements Templates {
  @override
  String renderCategory(CategoryTemplateData context) =>
      aot_renderers_for_md.renderCategory(context);

  @override
  String renderClass<T extends Class>(ClassTemplateData<T> context) =>
      aot_renderers_for_md.renderClass(context);

  @override
  String renderConstructor(ConstructorTemplateData context) =>
      aot_renderers_for_md.renderConstructor(context);

  @override
  String renderEnum(EnumTemplateData context) =>
      aot_renderers_for_md.renderEnum(context);

  @override
  String renderError(PackageTemplateData context) =>
      aot_renderers_for_md.renderError(context);

  @override
  String renderExtension(ExtensionTemplateData context) =>
      aot_renderers_for_md.renderExtension(context);

  @override
  String renderFunction(FunctionTemplateData context) =>
      aot_renderers_for_md.renderFunction(context);

  @override
  String renderIndex(PackageTemplateData context) =>
      aot_renderers_for_md.renderIndex(context);

  @override
  String renderLibrary(LibraryTemplateData context) =>
      aot_renderers_for_md.renderLibrary(context);

  @override
  String renderMethod(MethodTemplateData context) =>
      aot_renderers_for_md.renderMethod(context);

  @override
  String renderMixin(MixinTemplateData context) =>
      aot_renderers_for_md.renderMixin(context);

  @override
  String renderProperty(PropertyTemplateData context) =>
      aot_renderers_for_md.renderProperty(context);

  @override
  String renderSidebarForContainer(
          TemplateDataWithContainer<Documentable> context) =>
      aot_renderers_for_md.renderSidebarForContainer(context);

  @override
  String renderSidebarForLibrary(
          TemplateDataWithLibrary<Documentable> context) =>
      aot_renderers_for_md.renderSidebarForLibrary(context);

  @override
  String renderTopLevelProperty(TopLevelPropertyTemplateData context) =>
      aot_renderers_for_md.renderTopLevelProperty(context);

  @override
  String renderTypedef(TypedefTemplateData context) =>
      aot_renderers_for_md.renderTypedef(context);
}

/// The collection of [Template] objects parsed at runtime.
class RuntimeTemplates implements Templates {
  @override
  String renderCategory(CategoryTemplateData context) =>
      runtime_renderers.renderCategory(context, _categoryTemplate);

  @override
  String renderClass<T extends Class>(ClassTemplateData<T> context) =>
      runtime_renderers.renderClass(context, _classTemplate);

  @override
  String renderConstructor(ConstructorTemplateData context) =>
      runtime_renderers.renderConstructor(context, _constructorTemplate);

  @override
  String renderEnum(EnumTemplateData context) =>
      runtime_renderers.renderEnum(context, _enumTemplate);

  @override
  String renderError(PackageTemplateData context) =>
      runtime_renderers.renderError(context, _errorTemplate);

  @override
  String renderExtension(ExtensionTemplateData context) =>
      runtime_renderers.renderExtension(context, _extensionTemplate);

  @override
  String renderFunction(FunctionTemplateData context) =>
      runtime_renderers.renderFunction(context, _functionTemplate);

  @override
  String renderIndex(PackageTemplateData context) =>
      runtime_renderers.renderIndex(context, _indexTemplate);

  @override
  String renderLibrary(LibraryTemplateData context) =>
      runtime_renderers.renderLibrary(context, _libraryTemplate);

  @override
  String renderMethod(MethodTemplateData context) =>
      runtime_renderers.renderMethod(context, _methodTemplate);

  @override
  String renderMixin(MixinTemplateData context) =>
      runtime_renderers.renderMixin(context, _mixinTemplate);

  @override
  String renderProperty(PropertyTemplateData context) =>
      runtime_renderers.renderProperty(context, _propertyTemplate);

  @override
  String renderSidebarForContainer(
          TemplateDataWithContainer<Documentable> context) =>
      runtime_renderers.renderSidebarForContainer(
          context, _sidebarContainerTemplate);

  @override
  String renderSidebarForLibrary(
          TemplateDataWithLibrary<Documentable> context) =>
      runtime_renderers.renderSidebarForLibrary(
          context, _sidebarLibraryTemplate);

  @override
  String renderTopLevelProperty(TopLevelPropertyTemplateData context) =>
      runtime_renderers.renderTopLevelProperty(
          context, _topLevelPropertyTemplate);

  @override
  String renderTypedef(TypedefTemplateData context) =>
      runtime_renderers.renderTypedef(context, _typedefTemplate);

  final Template _categoryTemplate;
  final Template _classTemplate;
  final Template _constructorTemplate;
  final Template _enumTemplate;
  final Template _errorTemplate;
  final Template _extensionTemplate;
  final Template _functionTemplate;
  final Template _indexTemplate;
  final Template _libraryTemplate;
  final Template _methodTemplate;
  final Template _mixinTemplate;
  final Template _propertyTemplate;
  final Template _sidebarContainerTemplate;
  final Template _sidebarLibraryTemplate;
  final Template _topLevelPropertyTemplate;
  final Template _typedefTemplate;

  /// Creates a [Templates] from a custom set of template files, found in [dir].
  static Future<Templates> _create(Folder dir, String format,
      {@required ResourceProvider resourceProvider}) async {
    Future<Template> loadTemplate(String templatePath) async {
      var templateFile = dir.getChildAssumingFile('$templatePath.$format');
      if (!templateFile.exists) {
        throw DartdocFailure(
            'Missing required template file: $templatePath.$format');
      }
      return Template.parse(templateFile,
          partialResolver: (String partialName) async =>
              dir.getChildAssumingFile('_$partialName.$format'));
    }

    var indexTemplate = await loadTemplate('index');
    var libraryTemplate = await loadTemplate('library');
    var sidebarContainerTemplate = await loadTemplate('_sidebar_for_container');
    var sidebarLibraryTemplate = await loadTemplate('_sidebar_for_library');
    var categoryTemplate = await loadTemplate('category');
    var classTemplate = await loadTemplate('class');
    var constructorTemplate = await loadTemplate('constructor');
    var enumTemplate = await loadTemplate('enum');
    var errorTemplate = await loadTemplate('404error');
    var extensionTemplate = await loadTemplate('extension');
    var functionTemplate = await loadTemplate('function');
    var methodTemplate = await loadTemplate('method');
    var mixinTemplate = await loadTemplate('mixin');
    var propertyTemplate = await loadTemplate('property');
    var topLevelPropertyTemplate = await loadTemplate('top_level_property');
    var typeDefTemplate = await loadTemplate('typedef');

    return RuntimeTemplates._(
      categoryTemplate,
      libraryTemplate,
      classTemplate,
      constructorTemplate,
      enumTemplate,
      errorTemplate,
      extensionTemplate,
      functionTemplate,
      indexTemplate,
      methodTemplate,
      mixinTemplate,
      propertyTemplate,
      sidebarContainerTemplate,
      sidebarLibraryTemplate,
      topLevelPropertyTemplate,
      typeDefTemplate,
    );
  }

  RuntimeTemplates._(
    this._categoryTemplate,
    this._libraryTemplate,
    this._classTemplate,
    this._constructorTemplate,
    this._enumTemplate,
    this._errorTemplate,
    this._extensionTemplate,
    this._functionTemplate,
    this._indexTemplate,
    this._methodTemplate,
    this._mixinTemplate,
    this._propertyTemplate,
    this._sidebarContainerTemplate,
    this._sidebarLibraryTemplate,
    this._topLevelPropertyTemplate,
    this._typedefTemplate,
  );
}
