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 [storeRoundTripInfo] 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.generate(reader.rules.length, (_) => []);
    var top = recursivelyFixUp(actualData, reader, ruleData);
    result["data"] = ruleData;
    result["roots"] = [top];
    return result;
  }

  /**
   * Convert nested references in [input] 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).toList();
    } else if (data is Map) {
      ruleNumber = data.remove(RULE);
    } else {
      throw new SerializationException("Invalid data format");
    }
    // Do not use map 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] = [];
    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;
  }
}
