// Copyright (c) 2017, 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/src/codegen/html.dart';
import 'package:html/dom.dart' as dom;
import 'package:html/parser.dart' as parser;
import 'package:path/path.dart';

import 'api.dart';

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

/**
 * 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;
  List<String> versions = <String>[];
  List<Domain> domains = <Domain>[];
  Types types = null;
  Refactorings refactorings = null;
  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 new Exception('The API must contain exactly one <version> element');
  }
  api = new 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 []}) {
  Set<String> attributesFound = new Set<String>();
  element.attributes.forEach((String name, String value) {
    if (!requiredAttributes.contains(name) &&
        !optionalAttributes.contains(name)) {
      throw new Exception(
          '$context: Unexpected attribute in ${element.localName}: $name');
    }
    attributesFound.add(name);
  });
  for (String expectedAttribute in requiredAttributes) {
    if (!attributesFound.contains(expectedAttribute)) {
      throw new 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) {
    if (context == null) {
      context = element.localName;
    }
    throw new 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');
  String name = html.attributes['name'];
  String context = name ?? 'domain';
  bool experimental = html.attributes['experimental'] == 'true';
  checkAttributes(html, ['name'], context,
      optionalAttributes: ['experimental']);
  List<Request> requests = <Request>[];
  List<Notification> notifications = <Notification>[];
  recurse(html, context, {
    'request': (dom.Element child) {
      requests.add(requestFromHtml(child, context));
    },
    'notification': (dom.Element child) {
      notifications.add(notificationFromHtml(child, context));
    }
  });
  return new Domain(name, requests, notifications, html,
      experimental: experimental);
}

dom.Element getAncestor(dom.Element html, String name, String context) {
  dom.Element ancestor = html.parent;
  while (ancestor != null) {
    if (ancestor.localName == name) {
      return ancestor;
    }
    ancestor = ancestor.parent;
  }
  throw new 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) {
  String domainName = getAncestor(html, 'domain', context).attributes['name'];
  checkName(html, 'notification', context);
  String event = html.attributes['event'];
  context = '$context.${event != null ? event : 'event'}';
  checkAttributes(html, ['event'], context);
  TypeDecl params;
  recurse(html, context, {
    'params': (dom.Element child) {
      params = typeObjectFromHtml(child, '$context.params');
    }
  });
  return new 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) {
  List<TypeDecl> types = processContentsAsTypes(html, context);
  if (types.length != 1) {
    throw new 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) {
  List<TypeDecl> types = <TypeDecl>[];
  recurse(html, context, {
    'object': (dom.Element child) {
      types.add(typeObjectFromHtml(child, context));
    },
    'list': (dom.Element child) {
      checkAttributes(child, [], context);
      types.add(new 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 new Exception('$context: Key type already specified');
          }
          keyType = processContentsAsType(child, '$context.key');
        },
        'value': (dom.Element child) {
          if (valueType != null) {
            throw new Exception('$context: Value type already specified');
          }
          valueType = processContentsAsType(child, '$context.value');
        }
      });
      if (keyType == null) {
        throw new Exception('$context: Key type not specified');
      }
      if (valueType == null) {
        throw new Exception('$context: Value type not specified');
      }
      types.add(new TypeMap(keyType, valueType, child));
    },
    'enum': (dom.Element child) {
      types.add(typeEnumFromHtml(child, context));
    },
    'ref': (dom.Element child) {
      checkAttributes(child, [], context);
      types.add(new TypeReference(innerText(child), child));
    },
    'union': (dom.Element child) {
      checkAttributes(child, ['field'], context);
      String field = child.attributes['field'];
      types.add(
          new TypeUnion(processContentsAsTypes(child, context), field, child));
    }
  });
  return types;
}

/**
 * Read the API description from the file 'spec_input.html'.  [pkgPath] is the
 * path to the current package.
 */
Api readApi(String pkgPath) {
  File htmlFile = new File(join(pkgPath, 'tool', 'spec', 'plugin_spec.html'));
  String htmlContents = htmlFile.readAsStringSync();
  dom.Document document = parser.parse(htmlContents);
  dom.Element htmlElement = document.children
      .singleWhere((element) => element.localName.toLowerCase() == 'html');
  return apiFromHtml(htmlElement);
}

void recurse(dom.Element parent, String context,
    Map<String, ElementProcessor> elementProcessors) {
  for (String key in elementProcessors.keys) {
    if (!specialElements.contains(key)) {
      throw new Exception('$context: $key is not a special element');
    }
  }
  for (dom.Node 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 new 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');
  String kind = html.attributes['kind'];
  String context = kind != null ? kind : 'refactoring';
  checkAttributes(html, ['kind'], context);
  TypeDecl feedback;
  TypeDecl options;
  recurse(html, context, {
    'feedback': (dom.Element child) {
      feedback = typeObjectFromHtml(child, '$context.feedback');
    },
    'options': (dom.Element child) {
      options = typeObjectFromHtml(child, '$context.options');
    }
  });
  return new 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');
  String context = 'refactorings';
  checkAttributes(html, [], context);
  List<Refactoring> refactorings = <Refactoring>[];
  recurse(html, context, {
    'refactoring': (dom.Element child) {
      refactorings.add(refactoringFromHtml(child));
    }
  });
  return new 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) {
  String domainName = getAncestor(html, 'domain', context).attributes['name'];
  checkName(html, 'request', context);
  String method = html.attributes['method'];
  context = '$context.${method != null ? method : 'method'}';
  checkAttributes(html, ['method'], context);
  TypeDecl params;
  TypeDecl result;
  recurse(html, context, {
    'params': (dom.Element child) {
      params = typeObjectFromHtml(child, '$context.params');
    },
    'result': (dom.Element child) {
      result = typeObjectFromHtml(child, '$context.result');
    }
  });
  return new Request(domainName, method, params, result, html);
}

/**
 * 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');
  String name = html.attributes['name'];
  String context = name != null ? name : 'type';
  checkAttributes(html, ['name'], context,
      optionalAttributes: ['experimental']);
  TypeDecl type = processContentsAsType(html, context);
  bool experimental = html.attributes['experimental'] == 'true';
  return new TypeDefinition(name, type, html, experimental: experimental);
}

/**
 * Create a [TypeEnum] from an HTML description.
 */
TypeEnum typeEnumFromHtml(dom.Element html, String context) {
  checkName(html, 'enum', context);
  checkAttributes(html, [], context);
  List<TypeEnumValue> values = <TypeEnumValue>[];
  recurse(html, context, {
    'value': (dom.Element child) {
      values.add(typeEnumValueFromHtml(child, context));
    }
  });
  return new 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);
  List<String> values = <String>[];
  recurse(html, context, {
    'code': (dom.Element child) {
      String text = innerText(child).trim();
      values.add(text);
    }
  });
  if (values.length != 1) {
    throw new Exception('$context: Exactly one value must be specified');
  }
  return new TypeEnumValue(values[0], html);
}

/**
 * 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);
  String name = html.attributes['name'];
  context = '$context.${name != null ? name : 'field'}';
  checkAttributes(html, ['name'], context,
      optionalAttributes: ['optional', 'value']);
  bool optional = false;
  String optionalString = html.attributes['optional'];
  if (optionalString != null) {
    switch (optionalString) {
      case 'true':
        optional = true;
        break;
      case 'false':
        optional = false;
        break;
      default:
        throw new Exception(
            '$context: field contains invalid "optional" attribute: "$optionalString"');
    }
  }
  String value = html.attributes['value'];
  TypeDecl type = processContentsAsType(html, context);
  return new TypeObjectField(name, type, html,
      optional: optional, value: value);
}

/**
 * Create a [TypeObject] from an HTML description.
 */
TypeObject typeObjectFromHtml(dom.Element html, String context) {
  checkAttributes(html, [], context, optionalAttributes: ['experimental']);
  List<TypeObjectField> fields = <TypeObjectField>[];
  recurse(html, context, {
    'field': (dom.Element child) {
      fields.add(typeObjectFieldFromHtml(child, context));
    }
  });
  bool experimental = html.attributes['experimental'] == 'true';
  return new 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');
  String context = 'types';
  checkAttributes(html, [], context);
  Map<String, TypeDefinition> types = <String, TypeDefinition>{};
  recurse(html, context, {
    'type': (dom.Element child) {
      TypeDefinition typeDefinition = typeDefinitionFromHtml(child);
      types[typeDefinition.name] = typeDefinition;
    }
  });
  return new Types(types, html);
}

typedef void ElementProcessor(dom.Element element);

typedef void TextProcessor(dom.Text text);
