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

library dart2js.serialization.json;

import 'dart:convert';
import 'keys.dart';
import 'serialization.dart';
import 'values.dart';

/// Serialization encoder for JSON.
class JsonSerializationEncoder implements SerializationEncoder {
  const JsonSerializationEncoder();

  String encode(ObjectValue objectValue) {
    return new JsonEncoder.withIndent(' ')
        .convert(const JsonValueEncoder().convert(objectValue));
  }
}

/// Serialization decoder for JSON.
class JsonSerializationDecoder implements SerializationDecoder {
  const JsonSerializationDecoder();

  Map decode(String text) => JSON.decode(text);

  /// Returns the name of the [key] which used for to store a [Key] into a
  /// [Map]; corresponding to the encoding of object properties in
  /// [JsonValueEncoder.visitObject].
  getObjectPropertyValue(Key key) => key.name;
}

/// A [ValueVisitor] that computes a JSON object value.
class JsonValueEncoder implements ValueVisitor {
  const JsonValueEncoder();

  convert(Value value) => visit(value, null);

  @override
  visit(Value value, [arg]) => value.accept(this, arg);

  @override
  bool visitBool(BoolValue value, arg) => value.value;

  @override
  visitConstant(ConstantValue value, arg) => visit(value.id);

  @override
  double visitDouble(DoubleValue value, arg) => value.value;

  @override
  visitElement(ElementValue value, arg) => visit(value.id);

  @override
  visitEnum(EnumValue value, arg) => value.value.index;

  @override
  int visitInt(IntValue value, arg) => value.value;

  @override
  List visitList(ListValue value, arg) => value.values.map(visit).toList();

  @override
  Map visitMap(MapValue value, arg) {
    Map<String, dynamic> map = <String, dynamic>{};
    value.map.forEach((String key, Value value) {
      map[key] = visit(value);
    });
    return map;
  }

  @override
  Map visitObject(ObjectValue value, arg) {
    Map<String, dynamic> map = <String, dynamic>{};
    value.map.forEach((Key key, Value value) {
      map[key.name] = visit(value);
    });
    return map;
  }

  @override
  String visitString(StringValue value, arg) => value.value;

  @override
  visitType(TypeValue value, arg) => visit(value.id);

  @override
  visitUri(UriValue value, arg) => '${value.value}';
}

/// [ValueVisitor] that generates a verbose JSON-like output.
class PrettyPrintEncoder implements ValueVisitor {
  StringBuffer buffer;

  String toText(Value value) {
    buffer = new StringBuffer();
    visit(value, '');
    String text = buffer.toString();
    buffer = null;
    return text;
  }

  @override
  void visit(Value value, String indentation) {
    value.accept(this, indentation);
  }

  @override
  void visitBool(BoolValue value, String indentation) {
    buffer.write(value.value);
  }

  @override
  void visitConstant(ConstantValue value, String indentation) {
    buffer.write('Constant(${value.id}):${value.constant.toDartText()}');
  }

  @override
  void visitDouble(DoubleValue value, String indentation) {
    buffer.write(value.value);
  }

  @override
  void visitElement(ElementValue value, String indentation) {
    buffer.write('Element(${value.id}):${value.element}');
  }

  @override
  void visitEnum(EnumValue value, String indentation) {
    buffer.write(value.value);
  }

  @override
  void visitInt(IntValue value, String indentation) {
    buffer.write(value.value);
  }

  @override
  void visitList(ListValue value, String indentation) {
    if (value.values.isEmpty) {
      buffer.write('[]');
    } else {
      buffer.write('[');
      bool needsComma = false;
      String nextIndentation = '${indentation}  ';
      for (Value element in value.values) {
        if (needsComma) {
          buffer.write(',');
        }
        buffer.write('\n$nextIndentation');
        visit(element, nextIndentation);
        needsComma = true;
      }
      buffer.write('\n$indentation]');
    }
  }

  @override
  void visitMap(MapValue value, String indentation) {
    if (value.map.isEmpty) {
      buffer.write('{}');
    } else {
      buffer.write('{');
      bool needsComma = false;
      String nextIndentation = '${indentation}  ';
      value.map.forEach((String key, Value subvalue) {
        if (needsComma) {
          buffer.write(',');
        }
        buffer.write('\n$nextIndentation$key: ');
        visit(subvalue, nextIndentation);
        needsComma = true;
      });
      buffer.write('\n$indentation}');
    }
  }

  @override
  void visitObject(ObjectValue value, String indentation) {
    if (value.map.isEmpty) {
      buffer.write('{}');
    } else {
      buffer.write('{');
      bool needsComma = false;
      String nextIndentation = '${indentation}  ';
      value.map.forEach((Key key, Value subvalue) {
        if (needsComma) {
          buffer.write(',');
        }
        buffer.write('\n$nextIndentation$key: ');
        visit(subvalue, nextIndentation);
        needsComma = true;
      });
      buffer.write('\n$indentation}');
    }
  }

  @override
  void visitString(StringValue value, String indentation) {
    buffer.write('"${value.value}"');
  }

  @override
  void visitType(TypeValue value, String indentation) {
    buffer.write('Type(${value.id}):${value.type}');
  }

  @override
  void visitUri(UriValue value, String indentation) {
    buffer.write('Uri(${value.value})');
  }
}
