// 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 reading an HTML API description.
import 'dart:io';

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

import 'api.dart';

/// Read the API description from the file 'plugin_spec.html'. [pkgPath] is the
/// path to the current package.
Api readApi(String pkgPath) {
  var reader = ApiReader(join(pkgPath, 'tool', 'spec', 'plugin_spec.html'));
  return reader.readApi();
}

typedef ElementProcessor = void Function(dom.Element element);

typedef TextProcessor = void Function(dom.Text text);

class ApiReader {
  static const List<String> specialElements = [
    'domain',
    'feedback',
    'object',
    'refactorings',
    'refactoring',
    'type',
    'types',
    'request',
    'notification',
    'params',
    'result',
    'field',
    'list',
    'map',
    'enum',
    'key',
    'value',
    'options',
    'ref',
    'code',
    'version',
    'union',
    'index',
    'include'
  ];

  /// The absolute and normalized path to the file being read.
  final String filePath;

  /// Initialize a newly created API reader to read from the file with the given
  /// [filePath].
  ApiReader(this.filePath);

  /// Create an [Api] object from an HTML representation such as:
  ///
  /// <html>
  ///   ...
  ///   <body>
  ///     ... <version>1.0</version> ...
  ///     <domain name="...">...</domain> <!-- zero or more -->
  ///     <types>...</types>
  ///     <refactorings>...</refactorings>
  ///   </body>
  /// </html>
  ///
  /// Child elements of <api> can occur in any order.
  Api apiFromHtml(dom.Element html) {
    Api api;
    var versions = <String>[];
    var domains = <Domain>[];
    Types? types;
    Refactorings? refactorings;
    recurse(html, 'api', {
      'domain': (dom.Element element) {
        domains.add(domainFromHtml(element));
      },
      'refactorings': (dom.Element element) {
        refactorings = refactoringsFromHtml(element);
      },
      'types': (dom.Element element) {
        types = typesFromHtml(element);
      },
      'version': (dom.Element element) {
        versions.add(innerText(element));
      },
      'index': (dom.Element element) {
        /* Ignore; generated dynamically. */
      }
    });
    if (versions.length != 1) {
      throw Exception('The API must contain exactly one <version> element');
    }
    api = Api(versions[0], domains, types!, refactorings, html);
    return api;
  }

  /// Check that the given [element] has all of the attributes in
  /// [requiredAttributes], possibly some of the attributes in
  /// [optionalAttributes], and no others.
  void checkAttributes(
      dom.Element element, List<String> requiredAttributes, String context,
      {List<String> optionalAttributes = const []}) {
    var attributesFound = <String>{};
    element.attributes.forEach((name, value) {
      if (!requiredAttributes.contains(name) &&
          !optionalAttributes.contains(name)) {
        throw Exception(
            '$context: Unexpected attribute in ${element.localName}: $name');
      }
      attributesFound.add(name as String);
    });
    for (var expectedAttribute in requiredAttributes) {
      if (!attributesFound.contains(expectedAttribute)) {
        throw Exception(
            '$context: ${element.localName} must contain attribute $expectedAttribute');
      }
    }
  }

  /// Check that the given [element] has the given [expectedName].
  void checkName(dom.Element element, String expectedName, [String? context]) {
    if (element.localName != expectedName) {
      context ??= element.localName;
      throw Exception(
          '$context: Expected $expectedName, found ${element.localName}');
    }
  }

  /// Create a [Domain] object from an HTML representation such as:
  ///
  /// <domain name="domainName">
  ///   <request method="...">...</request> <!-- zero or more -->
  ///   <notification event="...">...</notification> <!-- zero or more -->
  /// </domain>
  ///
  /// Child elements can occur in any order.
  Domain domainFromHtml(dom.Element html) {
    checkName(html, 'domain');
    var name = html.attributes['name'];
    var context = name ?? 'domain';
    var experimental = html.attributes['experimental'] == 'true';
    checkAttributes(html, ['name'], context,
        optionalAttributes: ['experimental']);
    var requests = <Request>[];
    var notifications = <Notification>[];
    recurse(html, context, {
      'request': (dom.Element child) {
        requests.add(requestFromHtml(child, context));
      },
      'notification': (dom.Element child) {
        notifications.add(notificationFromHtml(child, context));
      }
    });
    return Domain(name!, requests, notifications, html,
        experimental: experimental);
  }

  dom.Element getAncestor(dom.Element html, String name, String context) {
    var ancestor = html.parent;
    while (ancestor != null) {
      if (ancestor.localName == name) {
        return ancestor;
      }
      ancestor = ancestor.parent;
    }
    throw Exception(
        '$context: <${html.localName}> must be nested within <$name>');
  }

  /// Create a [Notification] object from an HTML representation such as:
  ///
  /// <notification event="methodName">
  ///   <params>...</params> <!-- optional -->
  /// </notification>
  ///
  /// Note that the event name should not include the domain name.
  ///
  /// <params> has the same form as <object>, as described in [typeDeclFromHtml].
  ///
  /// Child elements can occur in any order.
  Notification notificationFromHtml(dom.Element html, String context) {
    var domainName = getAncestor(html, 'domain', context).attributes['name']!;
    checkName(html, 'notification', context);
    var event = html.attributes['event'];
    context = '$context.${event ?? 'event'}';
    checkAttributes(html, ['event'], context);
    late TypeObject params;
    recurse(html, context, {
      'params': (dom.Element child) {
        params = typeObjectFromHtml(child, '$context.params');
      }
    });
    return Notification(domainName, event!, params, html);
  }

  /// Create a single of [TypeDecl] corresponding to the type defined inside the
  /// given HTML element.
  TypeDecl processContentsAsType(dom.Element html, String context) {
    var types = processContentsAsTypes(html, context);
    if (types.length != 1) {
      throw Exception('$context: Exactly one type must be specified');
    }
    return types[0];
  }

  /// Create a list of [TypeDecl]s corresponding to the types defined inside the
  /// given HTML element. The following forms are supported.
  ///
  /// To refer to a type declared elsewhere (or a built-in type):
  ///
  ///   <ref>typeName</ref>
  ///
  /// For a list: <list>ItemType</list>
  ///
  /// For a map: <map><key>KeyType</key><value>ValueType</value></map>
  ///
  /// For a JSON object:
  ///
  ///   <object>
  ///     <field name="...">...</field> <!-- zero or more -->
  ///   </object>
  ///
  /// For an enum:
  ///
  ///   <enum>
  ///     <value>...</value> <!-- zero or more -->
  ///   </enum>
  ///
  /// For a union type:
  ///   <union>
  ///     TYPE <!-- zero or more -->
  ///   </union>
  List<TypeDecl> processContentsAsTypes(dom.Element html, String context) {
    var types = <TypeDecl>[];
    recurse(html, context, {
      'object': (dom.Element child) {
        types.add(typeObjectFromHtml(child, context));
      },
      'list': (dom.Element child) {
        checkAttributes(child, [], context);
        types.add(TypeList(processContentsAsType(child, context), child));
      },
      'map': (dom.Element child) {
        checkAttributes(child, [], context);
        TypeDecl? keyType;
        TypeDecl? valueType;
        recurse(child, context, {
          'key': (dom.Element child) {
            if (keyType != null) {
              throw Exception('$context: Key type already specified');
            }
            keyType = processContentsAsType(child, '$context.key');
          },
          'value': (dom.Element child) {
            if (valueType != null) {
              throw Exception('$context: Value type already specified');
            }
            valueType = processContentsAsType(child, '$context.value');
          }
        });
        if (keyType == null) {
          throw Exception('$context: Key type not specified');
        }
        if (valueType == null) {
          throw Exception('$context: Value type not specified');
        }
        types.add(TypeMap(keyType as TypeReference, valueType!, child));
      },
      'enum': (dom.Element child) {
        types.add(typeEnumFromHtml(child, context));
      },
      'ref': (dom.Element child) {
        checkAttributes(child, [], context);
        types.add(TypeReference(innerText(child), child));
      },
      'union': (dom.Element child) {
        checkAttributes(child, ['field'], context);
        var field = child.attributes['field'];
        types.add(
            TypeUnion(processContentsAsTypes(child, context), field!, child));
      }
    });
    return types;
  }

  /// Read the API description from file with the given [filePath].
  Api readApi() {
    var htmlContents = File(filePath).readAsStringSync();
    var document = parser.parse(htmlContents);
    var htmlElement = document.children
        .singleWhere((element) => element.localName?.toLowerCase() == 'html');
    return apiFromHtml(htmlElement);
  }

  void recurse(dom.Element parent, String context,
      Map<String, ElementProcessor> elementProcessors) {
    for (var key in elementProcessors.keys) {
      if (!specialElements.contains(key)) {
        throw Exception('$context: $key is not a special element');
      }
    }
    for (var node in parent.nodes) {
      if (node is dom.Element) {
        if (elementProcessors.containsKey(node.localName)) {
          elementProcessors[node.localName]!(node);
        } else if (specialElements.contains(node.localName)) {
          throw Exception('$context: Unexpected use of <${node.localName}>');
        } else {
          recurse(node, context, elementProcessors);
        }
      }
    }
  }

  /// Create a [Refactoring] object from an HTML representation such as:
  ///
  /// <refactoring kind="refactoringKind">
  ///   <feedback>...</feedback> <!-- optional -->
  ///   <options>...</options> <!-- optional -->
  /// </refactoring>
  ///
  /// <feedback> and <options> have the same form as <object>, as described in
  /// [typeDeclFromHtml].
  ///
  /// Child elements can occur in any order.
  Refactoring refactoringFromHtml(dom.Element html) {
    checkName(html, 'refactoring');
    var kind = html.attributes['kind'];
    var context = kind ?? 'refactoring';
    checkAttributes(html, ['kind'], context);
    TypeObject? feedback;
    TypeObject? options;
    recurse(html, context, {
      'feedback': (dom.Element child) {
        feedback = typeObjectFromHtml(child, '$context.feedback');
      },
      'options': (dom.Element child) {
        options = typeObjectFromHtml(child, '$context.options');
      }
    });
    return Refactoring(kind!, feedback, options, html);
  }

  /// Create a [Refactorings] object from an HTML representation such as:
  ///
  /// <refactorings>
  ///   <refactoring kind="...">...</refactoring> <!-- zero or more -->
  /// </refactorings>
  Refactorings refactoringsFromHtml(dom.Element html) {
    checkName(html, 'refactorings');
    var context = 'refactorings';
    checkAttributes(html, [], context);
    var refactorings = <Refactoring>[];
    recurse(html, context, {
      'refactoring': (dom.Element child) {
        refactorings.add(refactoringFromHtml(child));
      }
    });
    return Refactorings(refactorings, html);
  }

  /// Create a [Request] object from an HTML representation such as:
  ///
  /// <request method="methodName">
  ///   <params>...</params> <!-- optional -->
  ///   <result>...</result> <!-- optional -->
  /// </request>
  ///
  /// Note that the method name should not include the domain name.
  ///
  /// <params> and <result> have the same form as <object>, as described in
  /// [typeDeclFromHtml].
  ///
  /// Child elements can occur in any order.
  Request requestFromHtml(dom.Element html, String context) {
    var domainName = getAncestor(html, 'domain', context).attributes['name']!;
    checkName(html, 'request', context);
    var method = html.attributes['method'];
    context = '$context.${method ?? 'method'}';
    checkAttributes(html, ['method'], context,
        optionalAttributes: ['experimental', 'deprecated']);
    var experimental = html.attributes['experimental'] == 'true';
    var deprecated = html.attributes['deprecated'] == 'true';
    TypeObject? params;
    TypeObject? result;
    recurse(html, context, {
      'params': (dom.Element child) {
        params = typeObjectFromHtml(child, '$context.params');
      },
      'result': (dom.Element child) {
        result = typeObjectFromHtml(child, '$context.result');
      }
    });
    return Request(domainName, method!, params, result, html,
        experimental: experimental, deprecated: deprecated);
  }

  /// Create a [TypeDefinition] object from an HTML representation such as:
  ///
  /// <type name="typeName">
  ///   TYPE
  /// </type>
  ///
  /// Where TYPE is any HTML that can be parsed by [typeDeclFromHtml].
  ///
  /// Child elements can occur in any order.
  TypeDefinition typeDefinitionFromHtml(dom.Element html) {
    checkName(html, 'type');
    var name = html.attributes['name'];
    var context = name ?? 'type';
    checkAttributes(html, ['name'], context,
        optionalAttributes: ['experimental', 'deprecated']);
    var type = processContentsAsType(html, context);
    var experimental = html.attributes['experimental'] == 'true';
    var deprecated = html.attributes['deprecated'] == 'true';
    return TypeDefinition(name!, type, html,
        experimental: experimental, deprecated: deprecated);
  }

  /// Create a [TypeEnum] from an HTML description.
  TypeEnum typeEnumFromHtml(dom.Element html, String context) {
    checkName(html, 'enum', context);
    checkAttributes(html, [], context);
    var values = <TypeEnumValue>[];
    recurse(html, context, {
      'value': (dom.Element child) {
        values.add(typeEnumValueFromHtml(child, context));
      }
    });
    return TypeEnum(values, html);
  }

  /// Create a [TypeEnumValue] from an HTML description such as:
  ///
  /// <enum>
  ///   <code>VALUE</code>
  /// </enum>
  ///
  /// Where VALUE is the text of the enumerated value.
  ///
  /// Child elements can occur in any order.
  TypeEnumValue typeEnumValueFromHtml(dom.Element html, String context) {
    checkName(html, 'value', context);
    checkAttributes(html, [], context, optionalAttributes: ['deprecated']);
    var deprecated = html.attributes['deprecated'] == 'true';
    var values = <String>[];
    recurse(html, context, {
      'code': (dom.Element child) {
        var text = innerText(child).trim();
        values.add(text);
      }
    });
    if (values.length != 1) {
      throw Exception('$context: Exactly one value must be specified');
    }
    return TypeEnumValue(values[0], html, deprecated: deprecated);
  }

  /// Create a [TypeObjectField] from an HTML description such as:
  ///
  /// <field name="fieldName">
  ///   TYPE
  /// </field>
  ///
  /// Where TYPE is any HTML that can be parsed by [typeDeclFromHtml].
  ///
  /// In addition, the attribute optional="true" may be used to specify that the
  /// field is optional, and the attribute value="..." may be used to specify
  /// that the field is required to have a certain value.
  ///
  /// Child elements can occur in any order.
  TypeObjectField typeObjectFieldFromHtml(dom.Element html, String context) {
    checkName(html, 'field', context);

    var name = html.attributes['name'];
    if (name == null) {
      throw Exception('$context: name not specified');
    }

    context = '$context.$name';
    checkAttributes(html, ['name'], context,
        optionalAttributes: [
          'optional',
          'value',
          'deprecated',
          'experimental'
        ]);
    var deprecated = html.attributes['deprecated'] == 'true';
    var experimental = html.attributes['experimental'] == 'true';
    var optional = false;
    var optionalString = html.attributes['optional'];
    if (optionalString != null) {
      switch (optionalString) {
        case 'true':
          optional = true;
          break;
        case 'false':
          optional = false;
          break;
        default:
          throw Exception(
              '$context: field contains invalid "optional" attribute: "$optionalString"');
      }
    }
    var value = html.attributes['value'];
    var type = processContentsAsType(html, context);
    return TypeObjectField(name, type, html,
        optional: optional,
        value: value,
        deprecated: deprecated,
        experimental: experimental);
  }

  /// Create a [TypeObject] from an HTML description.
  TypeObject typeObjectFromHtml(dom.Element html, String context) {
    checkAttributes(html, [], context, optionalAttributes: ['experimental']);
    var fields = <TypeObjectField>[];
    recurse(html, context, {
      'field': (dom.Element child) {
        fields.add(typeObjectFieldFromHtml(child, context));
      }
    });
    var experimental = html.attributes['experimental'] == 'true';
    return TypeObject(fields, html, experimental: experimental);
  }

  /// Create a [Types] object from an HTML representation such as:
  ///
  /// <types>
  ///   <type name="...">...</type> <!-- zero or more -->
  /// </types>
  Types typesFromHtml(dom.Element html) {
    checkName(html, 'types');
    var context = 'types';
    checkAttributes(html, [], context);
    var importUris = <String>[];
    var typeMap = <String, TypeDefinition>{};
    var childElements = <dom.Element>[];
    recurse(html, context, {
      'include': (dom.Element child) {
        var importUri = child.attributes['import'];
        if (importUri != null) {
          importUris.add(importUri);
        }
        var relativePath = child.attributes['path'];
        var path = normalize(join(dirname(filePath), relativePath));
        var reader = ApiReader(path);
        var api = reader.readApi();
        for (var typeDefinition in api.types) {
          typeDefinition.isExternal = true;
          childElements.add(typeDefinition.html!);
          typeMap[typeDefinition.name] = typeDefinition;
        }
      },
      'type': (dom.Element child) {
        var typeDefinition = typeDefinitionFromHtml(child);
        typeMap[typeDefinition.name] = typeDefinition;
      }
    });
    for (var element in childElements) {
      html.append(element);
    }
    var types = Types(typeMap, html);
    types.importUris.addAll(importUris);
    return types;
  }
}
