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

/// Code for displaying the API as HTML.  This is used both for generating a
/// full description of the API as a web page, and for generating doc comments
/// in generated code.
import 'dart:convert';

import 'package:analyzer_utilities/html.dart';
import 'package:analyzer_utilities/tools.dart';
import 'package:html/dom.dart' as dom;

import 'api.dart';
import 'from_html.dart';

/// Embedded stylesheet
final String stylesheet = '''
body {
  font-family: 'Roboto', sans-serif;
  max-width: 800px;
  margin: 0 auto;
  padding: 0 16px;
  font-size: 16px;
  line-height: 1.5;
  color: #111;
  background-color: #fdfdfd;
  font-weight: 300;
  -webkit-font-smoothing: auto;
}

h2, h3, h4, h5 {
  margin-bottom: 0;
}

h2.domain {
  border-bottom: 1px solid rgb(200, 200, 200);
  margin-bottom: 0.5em;
}

h4 {
  font-size: 18px;
}

h5 {
  font-size: 16px;
}

p {
  margin-top: 0;
}

pre {
  margin: 0;
  font-family: 'Roboto Mono', monospace;
  font-size: 15px;
}

div.box {
  background-color: rgb(240, 245, 240);
  border-radius: 4px;
  padding: 4px 12px;
  margin: 16px 0;
}

div.hangingIndent {
  padding-left: 3em;
  text-indent: -3em;
}

dl dt {
  font-weight: bold;
}

dl dd {
  margin-left: 16px;
}

dt {
  margin-top: 1em;
}

dt.notification {
  font-weight: bold;
}

dt.refactoring {
  font-weight: bold;
}

dt.request {
  font-weight: bold;
}

dt.typeDefinition {
  font-weight: bold;
}

a {
  text-decoration: none;
}

a:focus, a:hover {
  text-decoration: underline;
}

.deprecated {
  text-decoration: line-through;
}

/* Styles for index */

.subindex ul {
  padding-left: 0;
  margin-left: 0;

  -webkit-margin-before: 0;
  -webkit-margin-start: 0;
  -webkit-padding-start: 0;

  list-style-type: none;
}
'''
    .trim();

final GeneratedFile target =
    GeneratedFile('doc/api.html', (String pkgPath) async {
  var visitor = ToHtmlVisitor(readApi(pkgPath));
  var document = dom.Document();
  document.append(dom.DocumentType('html', null, null));
  for (var node in visitor.collectHtml(visitor.visitApi)) {
    document.append(node);
  }
  return document.outerHtml;
});

String _toTitleCase(String str) {
  if (str.isEmpty) return str;
  return str.substring(0, 1).toUpperCase() + str.substring(1);
}

/// Visitor that records the mapping from HTML elements to various kinds of API
/// nodes.
class ApiMappings extends HierarchicalApiVisitor {
  Map<dom.Element, Domain> domains = <dom.Element, Domain>{};

  ApiMappings(Api api) : super(api);

  @override
  void visitDomain(Domain domain) {
    domains[domain.html] = domain;
  }
}

/// Helper methods for creating HTML elements.
mixin HtmlMixin {
  void anchor(String id, void Function() callback) {
    element('a', {'name': id}, callback);
  }

  void b(void Function() callback) => element('b', {}, callback);
  void body(void Function() callback) => element('body', {}, callback);
  void box(void Function() callback) {
    element('div', {'class': 'box'}, callback);
  }

  void br() => element('br', {});
  void dd(void Function() callback) => element('dd', {}, callback);
  void dl(void Function() callback) => element('dl', {}, callback);
  void dt(String cls, void Function() callback) =>
      element('dt', {'class': cls}, callback);
  void element(String name, Map<Object, String> attributes,
      [void Function() callback]);
  void gray(void Function() callback) =>
      element('span', {'style': 'color:#999999'}, callback);
  void h1(void Function() callback) => element('h1', {}, callback);
  void h2(String cls, void Function() callback) {
    return element('h2', {'class': cls}, callback);
  }

  void h3(void Function() callback) => element('h3', {}, callback);
  void h4(void Function() callback) => element('h4', {}, callback);
  void h5(void Function() callback) => element('h5', {}, callback);
  void hangingIndent(void Function() callback) =>
      element('div', {'class': 'hangingIndent'}, callback);
  void head(void Function() callback) => element('head', {}, callback);
  void html(void Function() callback) => element('html', {}, callback);
  void i(void Function() callback) => element('i', {}, callback);
  void li(void Function() callback) => element('li', {}, callback);
  void link(String id, void Function() callback,
      [Map<Object, String>? attributes]) {
    attributes ??= {};
    attributes['href'] = '#$id';
    element('a', attributes, callback);
  }

  void p(void Function() callback) => element('p', {}, callback);
  void pre(void Function() callback) => element('pre', {}, callback);
  void span(String cls, void Function() callback) =>
      element('span', {'class': cls}, callback);
  void title(void Function() callback) => element('title', {}, callback);
  void tt(void Function() callback) => element('tt', {}, callback);
  void ul(void Function() callback) => element('ul', {}, callback);
}

/// Visitor that generates HTML documentation of the API.
class ToHtmlVisitor extends HierarchicalApiVisitor
    with HtmlMixin, HtmlGenerator {
  /// Set of types defined in the API.
  Set<String> definedTypes = <String>{};

  /// Mappings from HTML elements to API nodes.
  ApiMappings apiMappings;

  ToHtmlVisitor(Api api)
      : apiMappings = ApiMappings(api),
        super(api) {
    apiMappings.visitApi();
  }

  /// Describe the payload of request, response, notification, refactoring
  /// feedback, or refactoring options.
  ///
  /// If [force] is true, then a section is inserted even if the payload is
  /// null.
  void describePayload(TypeObject? subType, String name, {bool force = false}) {
    if (force || subType != null) {
      h4(() {
        write(name);
      });
      if (subType == null) {
        p(() {
          write('none');
        });
      } else {
        visitTypeDecl(subType);
      }
    }
  }

  void generateDomainIndex(Domain domain) {
    h4(() {
      write(domain.name);
      write(' (');
      link('domain_${domain.name}', () => write('\u2191'));
      write(')');
    });
    if (domain.requests.isNotEmpty) {
      element('div', {'class': 'subindex'}, () {
        generateRequestsIndex(domain.requests);
        if (domain.notifications.isNotEmpty) {
          generateNotificationsIndex(domain.notifications);
        }
      });
    } else if (domain.notifications.isNotEmpty) {
      element('div', {'class': 'subindex'}, () {
        generateNotificationsIndex(domain.notifications);
      });
    }
  }

  void generateDomainsHeader() {
    h1(() {
      write('Domains');
    });
  }

  void generateIndex() {
    h3(() => write('Domains'));
    for (var domain in api.domains) {
      if (domain.experimental ||
          (domain.requests.isEmpty && domain.notifications.isEmpty)) {
        continue;
      }
      generateDomainIndex(domain);
    }

    generateTypesIndex(definedTypes);
    generateRefactoringsIndex(api.refactorings);
  }

  void generateNotificationsIndex(Iterable<Notification> notifications) {
    h5(() => write('Notifications'));
    element('div', {'class': 'subindex'}, () {
      element('ul', {}, () {
        for (var notification in notifications) {
          element(
              'li',
              {},
              () => link('notification_${notification.longEvent}',
                  () => write(notification.event)));
        }
      });
    });
  }

  void generateRefactoringsIndex(Iterable<Refactoring> refactorings) {
    h3(() {
      write('Refactorings');
      write(' (');
      link('refactorings', () => write('\u2191'));
      write(')');
    });
    // TODO: Individual refactorings are not yet hyperlinked.
    element('div', {'class': 'subindex'}, () {
      element('ul', {}, () {
        for (var refactoring in refactorings) {
          element(
              'li',
              {},
              () => link('refactoring_${refactoring.kind}',
                  () => write(refactoring.kind)));
        }
      });
    });
  }

  void generateRequestsIndex(Iterable<Request> requests) {
    h5(() => write('Requests'));
    element('ul', {}, () {
      for (var request in requests) {
        if (!request.experimental) {
          element(
              'li',
              {},
              () => link('request_${request.longMethod}',
                  () => write(request.method)));
        }
      }
    });
  }

  void generateTableOfContents() {
    for (var domain in api.domains.where((domain) => !domain.experimental)) {
      if (domain.experimental) continue;

      writeln();

      p(() {
        link('domain_${domain.name}', () {
          write(_toTitleCase(domain.name));
        });
      });

      ul(() {
        for (var request in domain.requests) {
          if (request.experimental) continue;

          li(() {
            link('request_${request.longMethod}', () {
              write(request.longMethod);
            }, request.deprecated ? {'class': 'deprecated'} : null);
          });
          writeln();
        }
      });

      writeln();
    }
  }

  void generateTypesIndex(Set<String> types) {
    h3(() {
      write('Types');
      write(' (');
      link('types', () => write('\u2191'));
      write(')');
    });
    var sortedTypes = types.toList();
    sortedTypes.sort();
    element('div', {'class': 'subindex'}, () {
      element('ul', {}, () {
        for (var type in sortedTypes) {
          element('li', {}, () => link('type_$type', () => write(type)));
        }
      });
    });
  }

  void javadocParams(TypeObject? typeObject) {
    if (typeObject != null) {
      for (var field in typeObject.fields) {
        hangingIndent(() {
          write('@param ${field.name} ');
          translateHtml(field.html, squashParagraphs: true);
        });
      }
    }
  }

  /// Generate a description of [type] using [TypeVisitor].
  ///
  /// If [shortDesc] is non-null, the output is prefixed with this string
  /// and a colon.
  ///
  /// If [typeForBolding] is supplied, then fields in this type are shown in
  /// boldface.
  void showType(String? shortDesc, TypeDecl type,
      [TypeObject? typeForBolding]) {
    var fieldsToBold = <String>{};
    if (typeForBolding != null) {
      for (var field in typeForBolding.fields) {
        fieldsToBold.add(field.name);
      }
    }
    pre(() {
      if (shortDesc != null) {
        write('$shortDesc: ');
      }
      var typeVisitor = TypeVisitor(api, fieldsToBold: fieldsToBold);
      addAll(typeVisitor.collectHtml(() {
        typeVisitor.visitTypeDecl(type);
      }));
    });
  }

  /// Copy the contents of the given HTML element, translating the special
  /// elements that define the API appropriately.
  void translateHtml(dom.Element? html, {bool squashParagraphs = false}) {
    if (html == null) {
      return;
    }
    for (var node in html.nodes) {
      if (node is dom.Element) {
        var localName = node.localName!;
        if (squashParagraphs && localName == 'p') {
          translateHtml(node, squashParagraphs: squashParagraphs);
          continue;
        }
        switch (localName) {
          case 'domains':
            generateDomainsHeader();
            break;
          case 'domain':
            visitDomain(apiMappings.domains[node]!);
            break;
          case 'head':
            head(() {
              translateHtml(node, squashParagraphs: squashParagraphs);
              element('link', {
                'rel': 'stylesheet',
                'href':
                    'https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400;700&family=Roboto:ital,wght@0,300;0,400;0,700;1,400&display=swap',
                'type': 'text/css'
              });
              element('style', {}, () {
                writeln(stylesheet);
              });
            });
            break;
          case 'refactorings':
            visitRefactorings(api.refactorings);
            break;
          case 'types':
            visitTypes(api.types);
            break;
          case 'version':
            translateHtml(node, squashParagraphs: squashParagraphs);
            break;
          case 'toc':
            generateTableOfContents();
            break;
          case 'index':
            generateIndex();
            break;
          default:
            if (!ApiReader.specialElements.contains(localName)) {
              element(localName, node.attributes, () {
                translateHtml(node, squashParagraphs: squashParagraphs);
              });
            }
        }
      } else if (node is dom.Text) {
        var text = node.text;
        write(text);
      }
    }
  }

  @override
  void visitApi() {
    var apiTypes = api.types.where((TypeDefinition td) => !td.experimental);
    definedTypes = apiTypes.map((TypeDefinition td) => td.name).toSet();

    html(() {
      translateHtml(api.html);
    });
  }

  @override
  void visitDomain(Domain domain) {
    if (domain.experimental) {
      return;
    }
    h2('domain', () {
      anchor('domain_${domain.name}', () {
        write('${domain.name} domain');
      });
    });
    translateHtml(domain.html);
    if (domain.requests.isNotEmpty) {
      h3(() {
        write('Requests');
      });
      dl(() {
        domain.requests.forEach(visitRequest);
      });
    }
    if (domain.notifications.isNotEmpty) {
      h3(() {
        write('Notifications');
      });
      dl(() {
        domain.notifications.forEach(visitNotification);
      });
    }
  }

  @override
  void visitNotification(Notification notification) {
    if (notification.experimental) {
      return;
    }
    dt('notification', () {
      anchor('notification_${notification.longEvent}', () {
        write(notification.longEvent);
      });
    });
    dd(() {
      box(() {
        showType(
            'notification', notification.notificationType, notification.params);
      });
      translateHtml(notification.html);
      describePayload(notification.params, 'parameters:');
    });
  }

  @override
  void visitRefactoring(Refactoring refactoring) {
    dt('refactoring', () {
      write(refactoring.kind);
    });
    dd(() {
      translateHtml(refactoring.html);
      describePayload(refactoring.feedback, 'Feedback:', force: true);
      describePayload(refactoring.options, 'Options:', force: true);
    });
  }

  @override
  void visitRefactorings(Refactorings refactorings) {
    translateHtml(refactorings.html);
    dl(() {
      super.visitRefactorings(refactorings);
    });
  }

  @override
  void visitRequest(Request request) {
    if (request.experimental) {
      return;
    }
    dt(request.deprecated ? 'request deprecated' : 'request', () {
      anchor('request_${request.longMethod}', () {
        write(request.longMethod);
      });
    });
    dd(() {
      box(() {
        showType('request', request.requestType, request.params);
        br();
        showType('response', request.responseType, request.result);
      });
      translateHtml(request.html);
      describePayload(request.params, 'parameters:');
      describePayload(request.result, 'returns:');
    });
  }

  @override
  void visitTypeDefinition(TypeDefinition typeDefinition) {
    if (typeDefinition.experimental) {
      return;
    }
    dt(
        typeDefinition.deprecated
            ? 'typeDefinition deprecated'
            : 'typeDefinition', () {
      anchor('type_${typeDefinition.name}', () {
        write('${typeDefinition.name}: ');
        var typeVisitor = TypeVisitor(api, short: true);
        addAll(typeVisitor.collectHtml(() {
          typeVisitor.visitTypeDecl(typeDefinition.type);
        }));
      });
    });
    dd(() {
      translateHtml(typeDefinition.html);
      visitTypeDecl(typeDefinition.type);
    });
  }

  @override
  void visitTypeEnum(TypeEnum typeEnum) {
    dl(() {
      super.visitTypeEnum(typeEnum);
    });
  }

  @override
  void visitTypeEnumValue(TypeEnumValue typeEnumValue) {
    var isDocumented = false;
    for (var node in typeEnumValue.html.nodes) {
      if ((node is dom.Element && node.localName != 'code') ||
          (node is dom.Text && node.text.trim().isNotEmpty)) {
        isDocumented = true;
        break;
      }
    }
    dt(typeEnumValue.deprecated ? 'value deprecated' : 'value', () {
      write(typeEnumValue.value);
    });
    if (isDocumented) {
      dd(() {
        translateHtml(typeEnumValue.html);
      });
    }
  }

  @override
  void visitTypeList(TypeList typeList) {
    visitTypeDecl(typeList.itemType);
  }

  @override
  void visitTypeMap(TypeMap typeMap) {
    visitTypeDecl(typeMap.valueType);
  }

  @override
  void visitTypeObject(TypeObject typeObject) {
    dl(() {
      super.visitTypeObject(typeObject);
    });
  }

  @override
  void visitTypeObjectField(TypeObjectField typeObjectField) {
    if (typeObjectField.experimental) {
      return;
    }
    dt('field', () {
      b(() {
        if (typeObjectField.deprecated) {
          span('deprecated', () {
            write(typeObjectField.name);
          });
        } else {
          write(typeObjectField.name);
        }
        if (typeObjectField.value != null) {
          write(' = ${json.encode(typeObjectField.value)}');
        } else {
          write(': ');
          var typeVisitor = TypeVisitor(api, short: true);
          addAll(typeVisitor.collectHtml(() {
            typeVisitor.visitTypeDecl(typeObjectField.type);
          }));
          if (typeObjectField.optional) {
            gray(() => write(' (optional)'));
          }
        }
      });
    });
    dd(() {
      translateHtml(typeObjectField.html);
    });
  }

  @override
  void visitTypeReference(TypeReference typeReference) {}

  @override
  void visitTypes(Types types) {
    translateHtml(types.html);
    dl(() {
      var sortedTypes = types.toList();
      sortedTypes.sort((TypeDefinition first, TypeDefinition second) =>
          first.name.compareTo(second.name));
      sortedTypes.forEach(visitTypeDefinition);
    });
  }
}

/// Visitor that generates a compact representation of a type, such as:
///
/// {
///   "id": String
///   "error": optional Error
///   "result": {
///     "version": String
///   }
/// }
class TypeVisitor extends HierarchicalApiVisitor
    with HtmlMixin, HtmlCodeGenerator {
  /// Set of fields which should be shown in boldface.
  final Set<String> fieldsToBold;

  /// True if a short description should be generated.  In a short description,
  /// objects are shown as simply "object", and enums are shown as "String".
  final bool short;

  TypeVisitor(Api api, {this.fieldsToBold = const {}, this.short = false})
      : super(api);

  @override
  void visitTypeEnum(TypeEnum typeEnum) {
    if (short) {
      write('String');
      return;
    }
    writeln('enum {');
    indent(() {
      for (var value in typeEnum.values) {
        writeln(value.value);
      }
    });
    write('}');
  }

  @override
  void visitTypeList(TypeList typeList) {
    write('List<');
    visitTypeDecl(typeList.itemType);
    write('>');
  }

  @override
  void visitTypeMap(TypeMap typeMap) {
    write('Map<');
    visitTypeDecl(typeMap.keyType);
    write(', ');
    visitTypeDecl(typeMap.valueType);
    write('>');
  }

  @override
  void visitTypeObject(TypeObject typeObject) {
    if (short) {
      write('object');
      return;
    }
    writeln('{');
    indent(() {
      for (var field in typeObject.fields) {
        if (field.experimental) continue;
        write('"');
        if (fieldsToBold.contains(field.name)) {
          b(() {
            write(field.name);
          });
        } else {
          write(field.name);
        }
        write('": ');
        if (field.value != null) {
          write(json.encode(field.value));
        } else {
          if (field.optional) {
            gray(() {
              write('optional');
            });
            write(' ');
          }
          visitTypeDecl(field.type);
        }
        writeln();
      }
    });
    write('}');
  }

  @override
  void visitTypeReference(TypeReference typeReference) {
    var displayName = typeReference.typeName;
    if (api.types.containsKey(typeReference.typeName)) {
      link('type_${typeReference.typeName}', () {
        write(displayName);
      });
    } else {
      write(displayName);
    }
  }

  @override
  void visitTypeUnion(TypeUnion typeUnion) {
    var verticalBarNeeded = false;
    for (var choice in typeUnion.choices) {
      if (verticalBarNeeded) {
        write(' | ');
      }
      visitTypeDecl(choice);
      verticalBarNeeded = true;
    }
  }
}
