part of serialization;

/**
 * An abstract class for serialization formats. Subclasses define how data
 * is read or written to a particular output mechanism.
 */
abstract class Format {
  /**
   * Return true if this format stores primitives in their own area and uses
   * references to them (e.g. [SimpleFlatFormat]) and false if primitives
   * are stored directly (e.g. [SimpleJsonFormat], [SimpleMapFormat]).
   */
  bool get shouldUseReferencesForPrimitives => false;

  /**
   * Generate output for [w] and return it. The particular form of the output
   * will depend on the format. The format can assume that [w] has data
   * generated by rules in a series of lists, and that each list will contain
   * either primitives (null, bool, num, String), Lists or Maps. The Lists or
   * Maps may contain any of the same things recursively, or may contain
   * Reference objects. For lists and maps the rule will tell us if they can
   * be of variable length or not. The format is allowed to operate
   * destructively on the rule data.
   */
  generateOutput(Writer w);

  /**
   * Read the data from [input] in the context of [reader] and return it as a
   * Map with entries for "roots", "data" and "rules", which the reader knows
   * how to interpret. The type of [input] will depend on the particular format.
   */
  Map<String, dynamic> read(input, Reader reader);
}

/**
 * A format that stores the data in maps which are converted into a JSON
 * string. Note that the maps aren't nested, and it handles cyclic references
 * by converting object references to [Reference] objects. If you want simple
 * acyclic JSON look at [SimpleJsonFormat].
 */
class SimpleMapFormat extends Format {

  /**
   * Generate output for this format from [w] and return it as a String which
   * is the [json] representation of a nested Map structure. The top level has
   * 3 fields, "rules" which may hold a definition of the rules used,
   * "data" which holds the serialized data, and "roots", which holds
   * [Reference] objects indicating the root objects. Note that roots are
   * necessary because the data is organized in the same way as the object
   * structure, it's a list of lists holding self-contained maps which only
   * refer to other parts via [Reference] objects.
   * This effectively defines a custom JSON serialization format, although
   * the details of the format vary depending which rules were used.
   */
  Map<String, dynamic> generateOutput(Writer w) {
    var result = {
      "rules" : w.serializedRules(),
      "data" : w.states,
      "roots" : w._rootReferences()
    };
    return result;
  }

  /**
   * Read a [json] compatible representation of serialized data in this format
   * and return the nested Map representation described in [generateOutput]. If
   * the data also includes rule definitions, then these will replace the rules
   * in the [Serialization] for [reader].
   */
  Map<String, dynamic> read(topLevel, Reader reader) {
    var ruleString = topLevel["rules"];
    reader.readRules(ruleString);
    return topLevel;
  }
}

/**
 * A format for "normal" [json] representation of objects. It stores
 * the fields of the objects as nested maps, and doesn't allow cycles. This can
 * be useful in talking to existing APIs that expect [json] format data. The
 * output will be either a simple object (string, num, bool), a List, or a Map,
 * with nesting of those.
 * Note that since the classes of objects aren't normally stored, this isn't
 * enough information to read back the objects. However, if the
 * If the [storeRoundTripData] field of the format is set to true, then this
 * will store the rule number along with the data, allowing reconstruction.
 */
class SimpleJsonFormat extends Format {

  /**
   * Indicate if we should store rule numbers with map/list data so that we
   * will know how to reconstruct it with a read operation. If we don't, this
   * will be more compliant with things that expect known format JSON as input,
   * but we won't be able to read back the objects.
   */
  final bool storeRoundTripInfo;

  /**
   * If we store the rule numbers, what key should we use to store them.
   */
  static final String RULE = "_rule";
  static final String RULES = "_rules";
  static final String DATA = "_data";
  static final String ROOTS = "_root";

  SimpleJsonFormat({this.storeRoundTripInfo : false});

  /**
   * Generate output for this format from [w] and return it as
   * the [json] representation of a nested Map structure.
   */
  generateOutput(Writer w) {
    jsonify(w);
    var root = w._rootReferences().first;
    if (root is Reference) root = w.stateForReference(root);
    if (w.selfDescribing && storeRoundTripInfo) {
      root = new Map()
          ..[RULES] = w.serializedRules()
          ..[DATA] = root;
    }
    return root;
  }

  /**
   * Convert the data generated by the rules to have nested maps instead
   * of Reference objects and to add rule numbers if [storeRoundTripInfo]
   * is true.
   */
  jsonify(Writer w) {
    for (var eachRule in w.rules) {
      var ruleData = w.states[eachRule.number];
      jsonifyForRule(ruleData, w, eachRule);
    }
  }

  /**
   * For a particular [rule] modify the [ruleData] to conform to this format.
   */
  jsonifyForRule(List ruleData, Writer w, SerializationRule rule) {
    for (var i = 0; i < ruleData.length; i++) {
      var each = ruleData[i];
      if (each is List) {
        jsonifyEntry(each, w);
        if (storeRoundTripInfo) ruleData[i].add(rule.number);
      } else if (each is Map) {
        jsonifyEntry(each, w);
        if (storeRoundTripInfo) each[RULE] = rule.number;
      }
    }
  }

  /**
   * For one particular entry, which is either a Map or a List, update it
   * to turn References into a nested List/Map.
   */
  jsonifyEntry(map, Writer w) {
    // Note, if this is a Map, and the key might be a reference, we need to
    // bend over backwards to avoid concurrent modifications. Non-string keys
    // won't actually work if we try to write this to json, but might happen
    // if e.g. sending between isolates.
    var updates = new Map();
    keysAndValues(map).forEach((key, value) {
      if (value is Reference) updates[key] = w.stateForReference(value);
    });
    updates.forEach((k, v) => map[k] = v);
  }

  /**
   * Read serialized data saved in this format, which should look like
   * either a simple type, a List or a Map and return the Map
   * representation that the reader expects, with top-level
   * entries for "rules", "data", and "roots". Nested lists/maps will be
   * converted into Reference objects. Note that if the data was not written
   * with [storeRoundTripInfo] true this will fail.
   */
  Map<String, dynamic> read(data, Reader reader) {
    var result = new Map();
    // Check the case of having been written without additional data and
    // read as if it had been written with storeRoundTripData set.
    if (reader.selfDescribing && !(data.containsKey(DATA))) {
      throw new SerializationException("Missing $DATA entry, "
          "may mean this was written and read with different values "
          "of selfDescribing.");
    }
    // If we are self-describing, we should have separate rule and data
    // sections. If not, we assume that we have just the data at the top level.
    var rules = reader.selfDescribing ? data[RULES] : null;
    var actualData = reader.selfDescribing ? data[DATA] : data;
    reader.readRules(rules);
    var ruleData = new List(reader.rules.length).map((x) => []).toList();
    var top = recursivelyFixUp(actualData, reader, ruleData);
    result["data"] = ruleData;
    result["roots"] = [top];
    return result;
  }

  /**
   * Convert nested references in [data] into [Reference] objects.
   */
  recursivelyFixUp(input, Reader r, List result) {
    var data = input;
    if (isPrimitive(data)) {
      result[r._primitiveRule().number].add(data);
      return data;
    }
    var ruleNumber;
    // If we've added the rule number on as the last item in a list we have
    // to get rid of it or it will be interpreted as extra data. For a map
    // the library will be ok, but we need to get rid of the extra key before
    // the data is shown to the user, so we destructively modify.
    if (data is List) {
      ruleNumber = data.last;
      data = data.take(data.length -1);
    } else if (data is Map) {
      ruleNumber = data.remove(RULE);
    } else {
      throw new SerializationException("Invalid data format");
    }
    // Do not use mappedBy or other lazy operations for this. They do not play
    // well with a function that destructively modifies its arguments.
    var newData = mapValues(data, (each) => recursivelyFixUp(each, r, result));
    result[ruleNumber].add(newData);
    return new Reference(r, ruleNumber, result[ruleNumber].length - 1);
  }
}

/**
 * Writes to a simple mostly-flat format. Details are subject to change.
 * Right now this produces a List containing null, num, and String. This is
 * more space-efficient than the map formats, but much less human-readable.
 * Simple usage is to turn this into JSON for transmission.
 */
class SimpleFlatFormat extends Format {
  bool get shouldUseReferencesForPrimitives => true;

  /**
   * For each rule we store data to indicate whether it will be reconstructed
   * as a primitive, a list or a map.
   */
  static final int STORED_AS_LIST = 1;
  static final int STORED_AS_MAP = 2;
  static final int STORED_AS_PRIMITIVE = 3;

  /**
   * Generate output for this format from [w]. This will return a List with
   * three entries, corresponding to the "rules", "data", and "roots" from
   * [SimpleMapFormat]. The data is stored as a single List containing
   * primitives.
   */
  List generateOutput(Writer w) {
    var result = new List(3);
    var flatData = [];
    for (var eachRule in w.rules) {
      var ruleData = w.states[eachRule.number];
      flatData.add(ruleData.length);
      writeStateInto(eachRule, ruleData, flatData);
    }
    result[0] = w.serializedRules();
    result[1] = flatData;
    result[2] = new List();
    w._rootReferences().forEach((x) => x.writeToList(result[2]));
    return result;
  }

  /**
   * Writes the data from [rule] into the [target] list.
   */
  void writeStateInto(SerializationRule rule, List ruleData, List target) {
    if (!ruleData.isEmpty) {
      var sample = ruleData.first;
      if (rule.storesStateAsLists || sample is List) {
        writeLists(rule, ruleData, target);
      } else if (rule.storesStateAsMaps || sample is Map) {
        writeMaps(rule, ruleData, target);
      } else if (rule.storesStateAsPrimitives || isPrimitive(sample)) {
        writeObjects(ruleData, target);
      } else {
        throw new SerializationException("Invalid data format");
      }
    } else {
      // If there is no data, write a zero for the length.
      target.add(0);
    }
  }

  /**
   * Write [entries], which contains Lists. Either the lists are variable
   * length, in which case we add a length field, or they are fixed length, in
   * which case we don't, and assume the [rule] will know how to read the
   * right length when we read it back. We expect everything in the list to be
   * a reference, which is stored as two numbers.
   */
  writeLists(SerializationRule rule, List<List> entries, List target) {
    target.add(STORED_AS_LIST);
    for (var eachEntry in entries) {
      if (rule.hasVariableLengthEntries) {
        target.add(eachEntry.length);
      }
      for (var eachReference in eachEntry) {
        writeReference(eachReference, target);
      }
    }
  }

  /**
   * Write [entries], which contains Maps. Either the Maps are variable
   * length, in which case we add a length field, or they are fixed length, in
   * which case we don't, and assume the [rule] will know how to read the
   * right length when we read it back. Then we write alternating keys and
   * values. We expect the values to be references, which we store as
   * two numbers.
   */
  writeMaps(SerializationRule rule, List<Map> entries, List target) {
    target.add(STORED_AS_MAP);
    for (var eachEntry in entries) {
      if (rule.hasVariableLengthEntries) {
        target.add(eachEntry.length);
      }
      eachEntry.forEach((key, value) {
        writeReference(key, target);
        writeReference(value, target);
      });
    }
  }

  /**
   * Write [entries], which contains simple objects which we can put directly
   * into [target].
   */
  writeObjects(List entries, List target) {
    target.add(STORED_AS_PRIMITIVE);
    for (var each in entries) {
      if (!isPrimitive(each)) throw new SerializationException("Invalid data");
    }
    target.addAll(entries);
  }

  /**
   * Write [eachRef] to [target]. It will be written as two ints. If [eachRef]
   * is null it will be written as two nulls.
   */
  void writeReference(Reference eachRef, List target) {
    // TODO(alanknight): Writing nulls is problematic in a real flat format.
    if (eachRef == null) {
      target..add(null)..add(null);
    } else {
      eachRef.writeToList(target);
    }
  }

  /**
   * Read the data from [rawInput] in the context of [r] and return it as a
   * Map with entries for "roots", "data" and "rules", which the reader knows
   * how to interpret. We expect [rawInput] to have been generated from this
   * format.
   */
  Map<String, dynamic> read(List rawInput, Reader r) {
    // TODO(alanknight): It's annoying to have to pass the reader around so
    // much, consider having the format be specific to a particular
    // serialization operation along with the reader and having it as a field.
    var input = {};
    input["rules"] = rawInput[0];
    r.readRules(input["rules"]);

    var flatData = rawInput[1];
    var stream = flatData.iterator;
    var tempData = new List(r.rules.length);
    for (var eachRule in r.rules) {
       tempData[eachRule.number] = readRuleDataFrom(stream, eachRule, r);
    }
    input["data"] = tempData;

    var roots = [];
    var rootsAsInts = rawInput[2].iterator;
    do {
      roots.add(nextReferenceFrom(rootsAsInts, r));
    } while (rootsAsInts.current != null);

    input["roots"] = roots;
    return input;
  }

  /**
   * Read the data for [rule] from [input] and return it.
   */
  readRuleDataFrom(Iterator input, SerializationRule rule, Reader r) {
    var numberOfEntries = _next(input);
    var entryType = _next(input);
    if (entryType == STORED_AS_LIST) {
      return readLists(input, rule, numberOfEntries, r);
    }
    if (entryType == STORED_AS_MAP) {
      return readMaps(input, rule, numberOfEntries, r);
    }
    if (entryType == STORED_AS_PRIMITIVE) {
      return readPrimitives(input, rule, numberOfEntries);
    }
    if (numberOfEntries == 0) {
      return [];
    } else {
      throw new SerializationException("Invalid data in serialization");
    }
  }

  /**
   * Read data for [rule] from [input] with [length] number of entries,
   * creating lists from the results.
   */
  readLists(Iterator input, SerializationRule rule, int length, Reader r) {
    var ruleData = [];
    for (var i = 0; i < length; i++) {
      var subLength =
          rule.hasVariableLengthEntries ? _next(input) : rule.dataLength;
      var subList = [];
      ruleData.add(subList);
      for (var j = 0; j < subLength; j++) {
        subList.add(nextReferenceFrom(input, r));
      }
    }
    return ruleData;
  }

  /**
   * Read data for [rule] from [input] with [length] number of entries,
   * creating maps from the results.
   */
  readMaps(Iterator input, SerializationRule rule, int length, Reader r) {
    var ruleData = [];
    for (var i = 0; i < length; i++) {
      var subLength =
          rule.hasVariableLengthEntries ? _next(input) : rule.dataLength;
      var map = new Map();
      ruleData.add(map);
      for (var j = 0; j < subLength; j++) {
        var key = nextReferenceFrom(input, r);
        var value = nextReferenceFrom(input, r);
        map[key] = value;
      }
    }
    return ruleData;
  }

  /**
   * Read data for [rule] from [input] with [length] number of entries,
   * treating the data as primitives that can be returned directly.
   */
  readPrimitives(Iterator input, SerializationRule rule, int length) {
    var ruleData = [];
    for (var i = 0; i < length; i++) {
      ruleData.add(_next(input));
    }
    return ruleData;
  }

  /** Read the next Reference from the input. */
  nextReferenceFrom(Iterator input, Reader r) {
    var a = _next(input);
    var b = _next(input);
    if (a == null) {
      return null;
    } else {
      return new Reference(r, a, b);
    }
  }

  /** Return the next element from the input. */
  _next(Iterator input) {
    input.moveNext();
    return input.current;
  }
}
