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

// @dart = 2.10

/// A [Node] is an abstract base class for all [Node]s parsed from json
/// constraints.
abstract class Node {
  Map<String, dynamic> toJson();
}

/// A [NamedNode] is an abstract base class for all [Node]s that have a name.
abstract class NamedNode extends Node {
  final String name;

  NamedNode(this.name);
}

/// A [UriAndPrefix] is a simple POD data type wrapping a uri and prefix.
class UriAndPrefix {
  final Uri uri;
  final String prefix;

  UriAndPrefix(this.uri, this.prefix);

  @override
  String toString() {
    return '$uri#$prefix';
  }

  static UriAndPrefix fromJson(String json) {
    var uriAndPrefix = json.split('#');
    if (uriAndPrefix.length != 2) {
      throw 'Invalid "import" "uri#prefix" value in $json';
    }
    var uri = Uri.parse(uriAndPrefix[0]);
    var prefix = uriAndPrefix[1];
    return UriAndPrefix(uri, prefix);
  }
}

/// A [ReferenceNode] is a [NamedNode] with a uri and prefix.
class ReferenceNode extends NamedNode {
  final UriAndPrefix _uriAndPrefix;
  Uri get uri => _uriAndPrefix.uri;
  String get prefix => _uriAndPrefix.prefix;

  ReferenceNode(String name, this._uriAndPrefix) : super(name);

  @override
  Map<String, dynamic> toJson() {
    return {
      'type': 'reference',
      'name': name,
      'import': _uriAndPrefix.toString()
    };
  }

  static ReferenceNode fromJson(Map<String, dynamic> nodeJson) {
    if (nodeJson['type'] != 'reference') {
      throw 'Unrecognized type for reference node: ${nodeJson['type']}.';
    }
    return ReferenceNode(
        nodeJson['name'], UriAndPrefix.fromJson(nodeJson['import']));
  }

  @override
  String toString() {
    return 'ReferenceNode(name=$name, uri=$uri, prefix=$prefix)';
  }
}

/// A [CombinerType] defines how to combine multiple [ReferenceNode]s in a
/// single step.
enum CombinerType { and, or }

CombinerType parseCombinerType(Map<String, dynamic> nodeJson) {
  String type = nodeJson['type'];
  switch (type) {
    case 'and':
      return CombinerType.and;
    case 'or':
      return CombinerType.or;
    default:
      throw 'Unrecognized Combiner $nodeJson';
  }
}

String combinerTypeToString(CombinerType type) {
  switch (type) {
    case CombinerType.and:
      return 'and';
    case CombinerType.or:
      return 'or';
  }
  throw 'Unreachable';
}

T _jsonLookup<T>(Map<String, dynamic> nodeJson, String key) {
  var value = nodeJson[key];
  if (value == null) {
    throw 'Missing "$key" key in $nodeJson';
  }
  return value;
}

NamedNode _jsonLookupNode(
    Map<String, dynamic> nodeJson, String key, Map<String, NamedNode> nameMap) {
  var node = nameMap[_jsonLookup(nodeJson, key)];
  if (node == null) {
    throw 'Invalid "$key" name in $nodeJson';
  }
  return node;
}

/// A [CombinerNode] is a [NamedNode] with a list of [ReferenceNode] children
/// and a [CombinerType] for combining them.
class CombinerNode extends NamedNode {
  final CombinerType type;
  final Set<ReferenceNode> nodes;

  CombinerNode(String name, this.type, this.nodes) : super(name);

  @override
  Map<String, dynamic> toJson() {
    return {
      'type': combinerTypeToString(type),
      'name': name,
      'nodes': nodes.map((node) => node.name).toList()
    };
  }

  static CombinerNode fromJson(
      Map<String, dynamic> nodeJson, Map<String, NamedNode> nameMap) {
    String name = _jsonLookup(nodeJson, 'name');
    List<dynamic> referencesJson = _jsonLookup(nodeJson, 'nodes');
    Set<ReferenceNode> references = {};
    for (String reference in referencesJson) {
      references.add(nameMap[reference]);
    }
    return CombinerNode(name, parseCombinerType(nodeJson), references);
  }

  @override
  String toString() {
    var nodeNames = nodes.map((node) => node.name).join(', ');
    return 'CombinerNode(name=$name, type=$type, nodes=$nodeNames)';
  }
}

/// An [OrderNode] is a [Node] without a name that indicates a temporal
/// constraint.
abstract class OrderNode extends Node {}

/// A [RelativeOrderNode] is an unnamed [Node] which defines a relative
/// load order between two [NamedNode]s.
class RelativeOrderNode extends OrderNode {
  final NamedNode predecessor;
  final NamedNode successor;

  RelativeOrderNode({this.predecessor, this.successor}) {
    // TODO(joshualitt) make these both required parameters.
    assert(this.predecessor != null && this.successor != null);
  }

  @override
  Map<String, dynamic> toJson() {
    return {
      'type': 'relative_order',
      'predecessor': predecessor.name,
      'successor': successor.name
    };
  }

  static RelativeOrderNode fromJson(
      Map<String, dynamic> nodeJson, Map<String, NamedNode> nameMap) {
    var predecessor = _jsonLookupNode(nodeJson, 'predecessor', nameMap);
    var successor = _jsonLookupNode(nodeJson, 'successor', nameMap);
    return RelativeOrderNode(predecessor: predecessor, successor: successor);
  }

  @override
  String toString() {
    return 'RelativeOrderNode(predecessor=${predecessor.name}, '
        'successor=${successor.name})';
  }
}

/// A [FuseNode] is an [OrderNode] with a list of [NamedNode] children.
/// A [FuseNode] joins its children into a strongly connected component.
class FuseNode extends OrderNode {
  final Set<NamedNode> nodes;

  FuseNode(this.nodes);

  @override
  Map<String, dynamic> toJson() {
    return {'type': 'fuse', 'nodes': nodes.map((node) => node.name).toList()};
  }

  static FuseNode fromJson(
      Map<String, dynamic> nodeJson, Map<String, NamedNode> nameMap) {
    List<dynamic> referencesJson = _jsonLookup(nodeJson, 'nodes');
    Set<NamedNode> nodes = {};
    for (String reference in referencesJson) {
      nodes.add(nameMap[reference]);
    }
    return FuseNode(nodes);
  }

  @override
  String toString() {
    var nodeNames = nodes.map((node) => node.name).join(', ');
    return 'FuseNode(nodes=$nodeNames)';
  }
}

/// A builder class for constructing constraint nodes.
typedef ReferenceNodeNamer = String Function(UriAndPrefix);

class ProgramSplitBuilder {
  final Map<String, NamedNode> namedNodes = {};
  ReferenceNodeNamer _referenceNodeNamer;

  /// 'uri#prefix' will become a key to reference this node in other builder
  /// calls.
  String _uriAndPrefixNamer(UriAndPrefix uriAndPrefix) =>
      uriAndPrefix.toString();

  /// Override the default reference node namer.
  set referenceNodeNamer(ReferenceNodeNamer namer) =>
      _referenceNodeNamer = namer;

  /// Returns the [ReferenceNodeNamer] to use for naming.
  ReferenceNodeNamer get referenceNodeNamer =>
      _referenceNodeNamer ?? _uriAndPrefixNamer;

  NamedNode _addNamedNode(NamedNode node) {
    if (namedNodes.containsKey(node.name)) {
      throw 'Node with name ${node.name} already exists: '
          '${namedNodes[node.name]}';
    }
    namedNodes[node.name] = node;
    return node;
  }

  NamedNode _lookupNamedNode(String nodeName) {
    if (!namedNodes.containsKey(nodeName)) {
      throw 'Missing reference node for $nodeName';
    }
    return namedNodes[nodeName];
  }

  ReferenceNode _lookupReferenceNode(String nodeName) {
    var node = _lookupNamedNode(nodeName);
    if (node is! ReferenceNode) {
      throw 'node $nodeName is not a ReferenceNode.';
    }
    return node as ReferenceNode;
  }

  /// Returns a [ReferenceNode] referencing [importUriAndPrefix].
  /// [ReferenceNode]s are typically created in bulk, by mapping over a list of
  /// strings of imports in the form 'uri#prefix'. In further builder calls,
  /// created nodes can be referenced by their namers, derived from calling
  /// [referenceNodeNamer] per [ReferenceNode].
  ReferenceNode referenceNode(String importUriAndPrefix) {
    var uriAndPrefix = UriAndPrefix.fromJson(importUriAndPrefix);
    var name = referenceNodeNamer(uriAndPrefix);
    return _addNamedNode(ReferenceNode(name, uriAndPrefix));
  }

  /// Creates an unnamed [RelativeOrderNode] referencing two [NamedNode]s.
  RelativeOrderNode orderNode(String predecessor, String successor) {
    return RelativeOrderNode(
        predecessor: _lookupNamedNode(predecessor),
        successor: _lookupNamedNode(successor));
  }

  /// Creates a [CombinerNode] which can be referenced by [name] in further
  /// calls to the builder.
  CombinerNode combinerNode(String name, Set<String> nodes, CombinerType type) {
    return _addNamedNode(
        CombinerNode(name, type, nodes.map(_lookupReferenceNode).toSet()));
  }

  /// Creates an 'and' [CombinerNode] which can be referenced by [name] in
  /// further calls to the builder.
  CombinerNode andNode(String name, Set<String> nodes) {
    return combinerNode(name, nodes, CombinerType.and);
  }

  /// Creates a [FuseNode], which is a type of [OrderNode] indicating a
  /// [Set<String>] nodes can always be loaded together.
  FuseNode fuseNode(Set<String> nodes) {
    return FuseNode(nodes.map(_lookupNamedNode).toSet());
  }

  /// Creates an 'or' [CombinerNode] which can be referenced by [name] in
  /// further calls to the builder.
  CombinerNode orNode(String name, Set<String> nodes) {
    return combinerNode(name, nodes, CombinerType.or);
  }
}

/// [ConstraintData] is a data object which contains the results of parsing json
/// program split constraints.
class ConstraintData {
  final List<NamedNode> named;
  final List<OrderNode> ordered;

  ConstraintData(this.named, this.ordered);
}
