// 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.
 */
library from.html;

import 'dart:io';

import 'package:html5lib/dom.dart' as dom;
import 'package:html5lib/parser.dart' as parser;

import 'api.dart';
import 'html_tools.dart';

/**
 * 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}');
  }
}

/**
 * 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}');
    }
  }
}

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'];

typedef void ElementProcessor(dom.Element element);
typedef void TextProcessor(dom.Text text);

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);
      }
    }
  }
}

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 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));
    }
  });
  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;
}

/**
 * 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 [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 [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);
}

/**
 * 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);
  TypeDecl type = processContentsAsType(html, context);
  return new TypeDefinition(name, type, html);
}

/**
 * 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 != null ? name : 'domain';
  checkAttributes(html, ['name'], context);
  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);
}

/**
 * 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 [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;
}

/**
 * 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 [TypeObject] from an HTML description.
 */
TypeObject typeObjectFromHtml(dom.Element html, String context) {
  checkAttributes(html, [], context);
  List<TypeObjectField> fields = <TypeObjectField>[];
  recurse(html, context, {
    'field': (dom.Element child) {
      fields.add(typeObjectFieldFromHtml(child, context));
    }
  });
  return new TypeObject(fields, 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
      );
}

/**
 * Read the API description from the file 'spec_input.html'.
 */
Api readApi() {
  File htmlFile = new File('spec_input.html');
  String htmlContents = htmlFile.readAsStringSync();
  dom.Document document = parser.parse(htmlContents);
  return apiFromHtml(document.firstChild);
}
