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.generate(reader.rules.length, (_) => []);
    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).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;
  }
}
